zoukankan      html  css  js  c++  java
  • Tree Restoration Gym

    There is a tree of n vertices. For each vertex a list of all its successors is known (not only direct ones). It is required to restore the tree or to say there is no such tree.

    Input

    The first line contains a single integer n (1 ≤ n ≤ 1000) — the number of vertices in the tree.

    Each of the next n lines contains an integer ci (0 ≤ ci ≤ n) — the number of successors of vertex i, and then ci distinct integers aij (1 ≤ aij ≤ n) — the indices of successors of vertex i.

    Output

    If the answer does not exist, output «NO».

    Otherwise, in the first line output «YES», and then output n - 1 lines containing two integers each — indices of parent and child. Pairs (parent, child) can be output in any order.

    Examples

    Input
    5
    4 2 3 4 5
    3 3 4 5
    2 4 5
    1 5
    0
    Output
    YES
    1 2
    2 3
    3 4
    4 5
    Input
    5
    4 2 3 4 5
    3 3 4 5
    0
    1 5
    0
    Output
    YES
    1 2
    2 3
    2 4
    4 5
    Input
    3
    3 2 3 1
    3 3 1 2
    3 1 2 3
    Output
    NO

    细节太多,大致先按子孙的数量排序。。。
    还是请看我的代码吧,写这篇博客,主要是提醒一下坑点。
    1.有环
    2.建出来好几课树
    3.自己不能当自己的儿子。
    4.每个儿子都不能漏
    数据一组:

    7
    5 2 3 4 5 6
    2 4 5
    2 6 7
    0
    0
    0
    0

    还要注意并查集不能压缩路径

    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<map>
    #include<set>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<ctime>
    #define fuck(x) cout<<#x<<" = "<<x<<endl;
    #define ls (t<<1)
    #define rs ((t<<1)+1)
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int maxn = 1024;
    const int inf = 2.1e9;
    const ll Inf = 999999999999999999;
    const int mod = 1000000007;
    const double eps = 1e-6;
    const double pi = acos(-1);
    bool vis[maxn];
    int num[maxn];
    int f[maxn];
    struct node
    {
        int id,sz;
    }a[maxn];
    vector<int>v[maxn];
    int n,m;
    
    bool cmp(node a,node b){
        return a.sz<b.sz;
    }
    
    int mx=1001;
    int getf(int x,int t){
        if(t==mx){return -1;}
        if(x==f[x])return x;
        return getf(f[x],t+1);
    }
    
    int get_num(int x,int t){
        if(t==mx){return -1;}
        num[x]++;
        if(x==f[x]){return x;}
        return get_num(f[x],t+1);
    }
    
    vector<int>tt;
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&m);f[i]=i;
            for(int j=1;j<=m;j++){
                int x;
                scanf("%d",&x);
                v[i].push_back(x);
                a[i].sz++;
            }
            a[i].id=i;
        }
    
        sort(a+1,a+1+n,cmp);
        bool flag=true;
        for(int i=1;i<=n;i++){
            int siz = a[i].sz;
            int id=a[i].id;
            for(int j=0;j<siz;j++){
                vis[v[id][j]]=true;
            }
            vis[id]=true;
            for(int j=0;j<siz;j++){
                int t1=getf(v[id][j],0);
                if(id==v[id][j]||t1==-1||!vis[t1]){flag=false;break;}
                if(t1==v[id][j]){tt.push_back(t1);}
            }
            int sz=tt.size();
            for(int j=0;j<sz;j++){
                f[tt[j]]=id;
            }
            tt.clear();
            if(!flag){break;}
            memset(vis,0,sizeof(vis));
        }
    
        int rec=0;
        for(int i=1;i<=n;i++){
            if(f[i]==i){rec++;}
            get_num(i,0);
        }
        for(int i=1;i<=n;i++){
            if(num[i]!=v[i].size()+1){flag=false;}
        }
        if(rec!=1){flag=false;}
    
        if(flag){
            printf("YES
    ");
            for(int i=1;i<=n;i++){
                if(f[i]!=i){printf("%d %d
    ",f[i],i);}
            }
        }
        else {
            printf("NO
    ");
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    「2020 新手必备 」极速入门 Retrofit + OkHttp 网络框架到实战,这一篇就够了!
    结合源码,重温 Android View 的事件处理知多少 ?
    Android 这 13 道 ContentProvider 面试题,你都会了吗?
    17 个必须掌握的 BroadcastReceiver 知识点「建议收藏」
    23 个重难点突破,带你吃透 Service 知识点「长达 1W+ 字」
    Activity 的 36 大难点,你会几个?「建议收藏」
    Python time模块
    vue项目的创建
    githunb和码云生成/添加SSH公钥
    weex打包apk步骤
  • 原文地址:https://www.cnblogs.com/ZGQblogs/p/10542983.html
Copyright © 2011-2022 走看看