zoukankan      html  css  js  c++  java
  • 并查集模板

    hdu1213

    简单模板

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cstdlib>
    #include<map>
    using namespace std;
    //hdu 1213
    int node[1000+10];
    
    int Find(int x)
    {
        if(node[x] == x)
            return x;
        //压缩
        int root = Find(node[x]);
        node[x] = root;
        return root;
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int n,m;
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;++i)
                node[i] = i;
            for(int i=0;i<m;++i)
            {
                int a,b,x,y;
                scanf("%d%d",&a,&b);
                x = Find(a);
                y = Find(b);
                if(x != y)
                {
                    node[x] = y;
                }
            }
            map<int,int> mii;
            int cnt = 0;
            for(int i=1;i<=n;++i)
            {
                int root = Find(i);
                pair<map<int,int>::iterator,bool> pmb = mii.insert(pair<int,int>(root,0));
                if(pmb.second)  ++cnt;
            }
            printf("%d
    ",cnt);
        }
        return 0;
    }
    
    /*
    100
    3 2
    1 2
    2 1
    */
    View Code

    hdu1232

    简单模板

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    using namespace std;
    
    int node[1000+10];
    
    int Find(int x)
    {
        if(node[x] == x)
            return x;
        int root = Find(node[x]);
        node[x] = root;
        return root;
    }
    
    int main()
    {
        int n,m;
        while(~scanf("%d",&n),n)
        {
            scanf("%d",&m);
            for(int i=1;i<=n;++i)
                node[i] = i;
            for(int i=0;i<m;++i)
            {
                int a,b,x,y;
                scanf("%d%d",&a,&b);
                x = Find(a);
                y = Find(b);
                if(x != y)
                    node[x] = y;
            }
            int cnt = 0;
            for(int i=1;i<=n;++i)
                if(node[i] == i)
                    ++cnt;
            printf("%d
    ",cnt-1);
        }
        return 0;
    }
    View Code

    hdu1272

    判断是否有环。该题只输入0 0,要求输出Yes

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    int node[100000+10];
    int vis[100000+10];
    int flag = 0;       //是否有环
    
    int Find(int x)
    {
        if(node[x] == x) return x;
        int y = Find(node[x]);
        node[x] = y;
        return y;
    }
    
    void Union(int a,int b)
    {
        if(a == b) return;
        int x = Find(a);
        int y = Find(b);
        if(x == y) flag = 1;
        else{node[x] = y;}
    }
    
    int main()
    {
        int a,b;
        while(true)
        {
            for(int i=0;i<=100000+10;++i)
                node[i] = i;
            memset(vis,0,sizeof(vis));
            flag = 0;
            while(~scanf("%d%d",&a,&b))
            {
                if(a==0 && b==0)  break;
                if(a==-1 && b==-1) break;
                if(!vis[a]){vis[a]=1;}
                if(!vis[b]){vis[b]=1;}
                Union(a,b);
            }
            if(a==-1 && b==-1) break;
            int p = 0;
            //确保只有一个连通图,p==1
            for(int i=1;i<100000+10;++i)
                if(vis[i]&&i == Find(i)) ++p;
            if(!flag && p<=1)
                printf("Yes
    ");
            else
                printf("No
    ");
        }
        return 0;
    }
    View Code

    hdu1325

    跟1272类似,但是退出条件为小于0,小于0.并且在原有无环的判断条件后,增加了根的入度为0,节点的入度为1,才能会树。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define N (10000+10)
    
    int node[N];
    int vis[N];
    int indegree[N];
    int tp;
    int flag;
    
    int Find(int x)
    {
        if(node[x] == x) return x;
        int y = Find(node[x]);
        node[x] = y;
        return y;
    }
    
    void Union(int a,int b)
    {
        if(a==b){flag = 1;return;}
        int x = Find(a);
        int y = Find(b);
        if(x==y) flag = 1;
        else node[x] = y;
    }
    
    int main()
    {
        int t=0;
        while(true)
        {
            int a,b;
            for(int i=0;i<N;++i)
                node[i] = i;
            memset(vis,0,sizeof(vis));
            memset(indegree,0,sizeof(indegree));
            tp = 0;
            flag = 0;
            while(~scanf("%d%d",&a,&b))
            {
                if(a==0&&b==0) break;
                if(a<0&&b<0) break;
                vis[a] = 1;
                vis[b] = 1;
                ++indegree[b];
                Union(b,a);
            }
            if(a<0&&b<0) break;
            for(int i=0;i<N;++i)
            {
                if(!vis[i]) continue;
                if(i == Find(i)) ++tp;
                if(i == Find(i) && indegree[i]!=0) flag = 1;
                if(i != Find(i) && indegree[i]!=1) flag = 1;
                //if(i == Find(i)) printf("test %d
    ",i);
                //if(i == Find(i)){printf("i=%d,indegree=%d
    ",i,indegree[i]);}
            }
            printf("Case %d ",++t);
            if(!flag && tp <= 1) printf("is a tree.
    ");
            else printf("is not a tree.
    ");
        }
        return 0;
    }
    View Code

    hdu1856

    当n等于0的时候,输出为1,虽然数组要10的七次方,但是仍可以用1325的方法解。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define N (10000000+10)
    
    int node[N];
    int cnt[N];
    
    int Find(int x)
    {
        if(node[x]==x) return x;
        int y = Find(node[x]);
        node[x] = y;
        return y;
    }
    
    void Union(int a,int b)
    {
        if(a==b) return;
        int x = Find(node[a]);
        int y = Find(node[b]);
        if(x!=y)
        {
            node[x] = y;
        }
    }
    
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            for(int i=0;i<N;++i)
                node[i] = i,cnt[i] = 0;
            for(int i=0;i<n;++i)
            {
                int a,b;
                scanf("%d%d",&a,&b);
                Union(a,b);
            }
            int MaxCnt = 1;
            for(int i=0;i<N;++i)
            {
                int y = Find(i);
                ++cnt[y];
                MaxCnt = MaxCnt > cnt[y] ? MaxCnt : cnt[y];
            }
            printf("%d
    ",MaxCnt);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Codeforces Global Round 2
    BZOJ4762 最小集合(动态规划+容斥原理)
    BZOJ4621 Tc605(动态规划)
    Luogu5289 十二省联考2019皮配(动态规划)
    Luogu5290 十二省联考2019春节十二响(贪心+启发式合并)
    Luogu5283 十二省联考2019异或粽子(trie/可持久化trie+堆)
    Luogu5284 十二省联考2019字符串问题(后缀数组+拓扑排序+线段树/主席树/KDTree)
    【转】Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask
    android Handler更新UI
    Android 四大组件之Activity生命周期
  • 原文地址:https://www.cnblogs.com/jlyg/p/7356992.html
Copyright © 2011-2022 走看看