• 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;
    }
  • 相关阅读:
    餐饮点菜控件
    数据模块池
    关于sqlite数据库
    PHP使用DateTime类做时间日期到字符串转换
    php字符串比较函数
    Xdebug开源PHP程序调试器
    ubuntu chmod 无法更改 文件夹权限 系统提示“不允许的操作 2、linux 如何修改只读文件 3、ubuntu安装
    ubuntu的命令day1
    linux用终端上传文件和文件家到远程的服务器
    Symfony学习--原创。。。。
  • 原文地址:https://www.cnblogs.com/zsben991126/p/11009260.html
Copyright © 2020-2023  润新知