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;
    }
  • 相关阅读:
    linux设置永久别名
    网站架构
    c#: 判断Firefox是否安装
    似是故人来
    Python: re.sub()第二个参数
    Python: AES加密与解密
    c#: Noto Sans字体如何支持韩文
    Inno Setup安装程序单例运行
    朵朵的二维码
    Python: 浅淡Python中的属性(property)
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5801469.html
Copyright © 2011-2022 走看看