zoukankan      html  css  js  c++  java
  • CodeForces 698B Fix a Tree

    并查集,构造。

    先看一下图的特殊性,按照这种输入方式,一个点的入度最多只有$1$,因此,问题不会特别复杂,画画图就能知道了。

    如果给出的序列中已经存在$a[i]=i$,那么随便取一个$a[i]=i$的$i$作为$root$,剩下的每一条边$a[i] o i$,可以用并查集来处理,如果发现某条边$a[i] o i$加入前$a[i]$与$i$已经在同一集合中,说明再加$a[i] o i$会导致成环,因此将$i$的$father$改成$root$即可,并将$i$与$root$合并。

    如果给出的序列中不存在$a[i]=i$,和上面的处理方法类似,唯一不同的是:找到第一条不能加入的边$a[i] o i$,将$i$的$father$改为$i$,并且$root$设置为$i$,之后出现不能加入的边和上面处理方法一样。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    const double pi=acos(-1.0),eps=1e-8;
    void File()
    {
        freopen("D:\in.txt","r",stdin);
        freopen("D:\out.txt","w",stdout);
    }
    template <class T>
    inline void read(T &x)
    {
        char c = getchar(); x = 0;while(!isdigit(c)) c = getchar();
        while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar();  }
    }
    
    const int maxn=200010;
    int f[maxn],a[maxn],n;
    
    int Find(int x)
    {
        if(x!=f[x]) f[x]=Find(f[x]);
        return f[x];
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        int root=-1; for(int i=1;i<=n;i++) if(a[i]==i) root=i;
        int num=0; for(int i=1;i<=n;i++) f[i]=i;
    
        for(int i=1; i<=n; i++)
        {
            if(i==root) continue;
            int fx=Find(i),fy=Find(a[i]);
            if(fx!=fy) f[fx]=fy;
            else
            {
                if(root==-1) a[i]=i, root=i, num++;
                else
                {
                    a[i]=root, num++;
                    fx=Find(root); fy=Find(i);
                    f[fx]=fy;
                }
            }
        }
        printf("%d
    ",num);
        for(int i=1; i<=n; i++) printf("%d ",a[i]);
        printf("
    ");
        return 0;
    }
  • 相关阅读:
    树链剖分( 洛谷P3384 )
    ZJOI 2015 诸神眷顾的幻想乡
    BZOJ 1002 [FJOI2007]轮状病毒
    洛谷 P1485 火枪打怪
    Luogu2860 [USACO06JAN]冗余路径Redundant Paths
    CF962F Simple Cycles Edges
    Luogu3605 [USACO17JAN]Promotion Counting晋升者计数
    Luogu2295 MICE
    CF341D Iahub and Xors
    CF617E XOR and Favorite Number
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5801469.html
Copyright © 2011-2022 走看看