zoukankan      html  css  js  c++  java
  • Codeforces698B【并查集+拆环】

    好题,好题,第一次写这个神秘的拆环。。
    题意:
    给你n个数,第i个数代表点i连向点a[i],
    将这副图变成树,求最小改变边的数量;
    思路:
    已知有向树的定义,
    除了根节点外每个节点都有且仅有一条边都指向它的父亲节点,
    而根节点有且仅有一条边指向自己。
    给出的图类型,
    1.环;
    2.独立的点;
    3.链;
    如果是独立的话,就是选定一个根节点然后,让其他根节点指向它;
    如果存在环的话,那么就是拆掉,选一个根结点。
    //存在自己指向自己,也就是根,如果存在自己指向自己就可以让树的根设为其中一个。
    //拆环具体操作,找链,标记,最后判断break出来的节点是否也是cnt

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N=2e5+10;
    vector<int>pp;
    int n;
    int a[N];
    int vis[N];
    bool v[N];
    
    int main()
    {
        pp.clear();
        memset(v,false,sizeof(v));
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            if(a[i]==i)
            {
                pp.push_back(i);
                v[i]=true;
            }
        }
        int num=pp.size();
        memset(vis,-1,sizeof(vis));
        int cnt=0;
        int pre,x;
        for(int i=1;i<=n;i++)
        {
            if(vis[i]==-1)
            {
                cnt++;
                x=i;
                while(vis[x]==-1)
                {
                    vis[x]=cnt;
                    pre=x;
                    x=a[x];
                }
                if(vis[x]==cnt)//存在环,拆环
                {
                    a[pre]=pre;
                }
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(a[i]==i&&!v[i])
                pp.push_back(i);
        }
        for(int i=1;i<pp.size();i++)
        {
            a[pp[i]]=pp[0];
        }
        if(num)
            cout<<pp.size()-1<<endl;
        else
            cout<<pp.size()<<endl;
        for(int i=1;i<=n;i++)
        {
            if(i!=1)
                printf(" ");
            printf("%d",a[i]);
        }
        return 0;
    }
  • 相关阅读:
    struts2之拦截器
    JavaWeb开发之HttpServletResponse
    JavaWeb开发之Servlet
    HTTP协议详解
    字符串
    数组
    第一个只出现一次的字符
    DDoS的类型及原理
    引用变量&和指针*的区别
    赋值运算符的重载
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/5934757.html
Copyright © 2011-2022 走看看