zoukankan      html  css  js  c++  java
  • bfs+dfs乱搞+类似拓扑排序——cf1182D

     代码不知道上了多少补丁。。终于过了

    用类似拓扑排序的办法收缩整棵树得到x,然后找到x直连的最远的和最近的点

    只有这三个点可能是根,依次判一下即可

    另外题解的第一种方法时找直径,然后判两端点+重心+所有直连重心的叶子节点,感觉这样子复杂度爆炸啊。。(如果是遍历所有叶子节点的话)

    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 200005
    struct Edge{int to,nxt;}e[maxn<<1];
    int head[maxn],tot;
    void init(){
        memset(head,-1,sizeof head);
        tot=0;
    }
    void add(int u,int v){
        e[tot].to=v;e[tot].nxt=head[u];head[u]=tot++;
    }
    int d[maxn],n,degree[maxn];
    void dfs1(int u,int pre,int deep){
        if(degree[u]>2)return;
        if(degree[u]==1){
            d[u]=deep;return;
        }
        for(int i=head[u];i!=-1;i=e[i].nxt){
            int v=e[i].to;
            if(v==pre)continue;
            dfs1(v,u,deep+1);
        }
    }
    
    int dis[maxn];
    int judge(int u){
        queue<int>q;
        memset(dis,0,sizeof dis);
        
        q.push(u);dis[u]=1;
        int tmp1=1,tmp2=degree[u];
        while(q.size()){
            int x=q.front();q.pop();
            if(dis[x]!=tmp1){
                tmp1=dis[x];
                tmp2=degree[x];
            }
            else if(tmp2!=degree[x])return 0;
            for(int i=head[x];i!=-1;i=e[i].nxt){
                int y=e[i].to;
                if(dis[y])continue;
                dis[y]=dis[x]+1;
                q.push(y);
            }
        }
        
        return 1;
    }
    
    int main(){
        init();
        cin>>n;
        if(n==1){
            puts("1");
            return 0;
        } 
        for(int i=1;i<n;i++) {
            int u,v;
            cin>>u>>v;
            add(u,v);add(v,u);
            degree[u]++,degree[v]++;
        }
        
        
        queue<int>q;
        int cnt=0,rt,tmp[maxn];
        memcpy(tmp,degree,sizeof degree);
        
        for(int i=1;i<=n;i++)
            if(degree[i]==1)
                q.push(i),cnt++;
        
        while(cnt!=n){
            int x=q.front();q.pop();
            for(int i=head[x];i!=-1;i=e[i].nxt){
                int y=e[i].to;
                if(tmp[y]==1)continue;
                else if(--tmp[y]==1){
                    q.push(y);
                    cnt++;
                    if(cnt==n)rt=y;
                }
            }
        }
        
        if(judge(rt)){cout<<rt;return 0;}
        
        memset(d,0,sizeof d);
        for(int i=head[rt];i!=-1;i=e[i].nxt){
            int v=e[i].to;
            dfs1(v,rt,1);
        }
        int Max=0,Min=1000000,s=-1;
        for(int i=1;i<=n;i++)
            if(d[i] && Max<d[i]){
                Max=d[i];s=i;
            }
        if(s!=-1){
            if(judge(s)){cout<<s;return 0;}
        }
        
        s=-1;
        for(int i=1;i<=n;i++)
            if(d[i] && Min>d[i]){
                Min=d[i],s=i;
            }
        if(s!=-1){
            if(judge(s)){cout<<s;return 0;}
        }
        
        cout<<-1;
    }
  • 相关阅读:
    C# winIO32位,64位的使用(运行时要用管理员身份)
    C#实现的三种方式实现模拟键盘按键
    C#打印日志的小技巧
    write wall ping ifconfig mail last traceroute netstat setup mount
    安装常用工具 zip unzip bzip2 gcc gcc++编译器 cmake编译器
    gzip/gunzip tar -zcf/-zxvf zip /unzip bzip2/bunzip2 tar -cjf/tar -xjf
    help
    Asp.Net 高性能框架 SqlSugar.ORM 2.3
    centos 查看版本(转)
    浅谈OCR之Tesseract
  • 原文地址:https://www.cnblogs.com/zsben991126/p/11009260.html
Copyright © 2011-2022 走看看