CF1975E 判这些条件充不充分?
  • 板块学术版
  • 楼主Resstifnurvˆwˆ.tar.gz
  • 当前回复6
  • 已保存回复6
  • 发布时间2024/5/26 01:50
  • 上次更新2024/5/26 10:06:33
查看原帖
CF1975E 判这些条件充不充分?
881015
Resstifnurvˆwˆ.tar.gz楼主2024/5/26 01:50

(抱歉又发帖子了)

如果把边的方向都视作从根节点往下,那么链大概有(↙↘ 或 ↓)两种形态。

维护出度入度,则:

  1. 不能有出度 ≥3\ge3 的点;

  2. 入度为 00 的点有且仅有一个(将其称作顶点)

  3. 出度为 00 的点的个数 == 顶点出度(一个黑点的情况特判一下)

(当然,肯定是没过去)

所以这些条件是否充要?

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;

inline int read(){
    int ret=0;
    char c=getchar();
    while(!('0'<=c&&c<='9')) c=getchar();
    while('0'<=c&&c<='9') ret=(ret*10)+(c^48),c=getchar();
    return ret;
}

int T,n,a,b;
const int N=2e5+10,M=4e5+10;

int to[M],nt[M],idx,h[N];
inline void add(int x,int y){
    to[idx]=y;
    nt[idx]=h[x];
    h[x]=idx++;
}

int depth[N],dad[N];
int son[N];
bool v[N];
void dfs1(int u,int fa){
    dad[u]=fa;
    depth[u]=depth[fa]+1;
    for(int i=h[u];i!=-1;i=nt[i]){
        int j=to[i];
        if(j==fa) continue;
        dfs1(j,u);
    }
}

int f[N],g[N];
void dfs(int u,int fa){
    f[u]=g[u]=0;
    int ma=0;
    for(int i=h[u];i!=-1;i=nt[i]){
        int j=to[i];
        if(j==fa) continue;
        dfs(j,u);
        g[u]+=2+g[j];
        ma=max(ma,g[j]-f[j]);
    }
    if(g[u]) f[u]=g[u]-1-ma;
}

inline void init(){
    for(int i=0;i<=n;i++){
        v[i]=false;
        h[i]=-1;
    }
    idx=0;
}
int main(){
    T=read();
    while(T--){
        n=read();
        init();
        a=read(),b=read();
        for(int i=1;i<n;i++){
            int x=read(),y=read();
            add(x,y);
            add(y,x);
        }
        dfs1(1,0);
        int s=a,t=b,lca=0;
        v[s]=v[t]=true;
        if(s==t) lca=a;
        while(true){
            if(lca) break;
            son[dad[s]]=s;
            s=dad[s];
            if(s&&v[s]){
                lca=s;
                break;
            }
            v[s]=true;
            son[dad[t]]=t;
            t=dad[t];
            if(t&&v[t]){
                lca=t;
                break;
            }
            v[t]=true;
        }
        int ans=depth[a]+depth[b]-2*depth[lca];
        int len=ans/2;
        ans=len+(ans&1);
        if(depth[a]-depth[lca]<=len){
            len-=depth[a]-depth[lca];
            while(len--) lca=son[lca];
        }
        else{
            lca=a;
            while(len--) lca=dad[lca];
        }
        dfs(lca,0);
        printf("%d\n",ans+f[lca]);
    }
    return 0;
}
2024/5/26 01:50
加载中...