• POJ-2492 A Bug's Life(种类并查集)


    http://poj.org/problem?id=2492

    题意:

    给出一个T代表几组数据,给出一个n一个m,代表人的编号由1~n,m条命令,每条命令由两个数值组成,代表这两个人性别不同,问所有命令是否符合逻辑

    两种写法:

    第一种:带权并查集

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <iostream>
     4 #include <string>
     5 #include <math.h>
     6 #include <algorithm>
     7 #include <vector>
     8 #include <stack>
     9 #include <queue>
    10 #include <set>
    11 #include <map>
    12 #include <sstream>
    13 const int INF=0x3f3f3f3f;
    14 typedef long long LL;
    15 const int mod=1e9+7;
    16 const int maxn=1e5+10;
    17 using namespace std;
    18 
    19 int fa[5005];
    20 int dis[5005];//表示i和其根结点的关系,1表示异性,0表示同性 
    21  
    22 void init(int n)
    23 {
    24     for(int i=0;i<=n;i++)
    25         dis[i]=0,fa[i]=i;
    26 }
    27 int Find(int x)//带权并查集 
    28 {
    29     if(x!=fa[x])
    30     {
    31         int t=fa[x];
    32         fa[x]=Find(fa[x]);
    33         dis[x]=(dis[x]+dis[t])%2;
    34     }
    35     return fa[x];
    36 }
    37 
    38 int main()
    39 {
    40     #ifdef DEBUG
    41     freopen("sample.txt","r",stdin);
    42     #endif
    43 //    ios_base::sync_with_stdio(false);
    44 //    cin.tie(NULL);
    45     
    46     int T;
    47     scanf("%d",&T);
    48     for(int k=1;k<=T;k++)
    49     {
    50         int n,m;
    51         scanf("%d %d",&n,&m);
    52         init(n);
    53         int flag=0;//flag=1表示找到了错误 
    54         for(int i=1;i<=m;i++)
    55         {
    56             int a,b;
    57             scanf("%d %d",&a,&b);
    58             if(flag) continue;
    59             int aa=Find(a);
    60             int bb=Find(b);
    61             if(aa==bb)// 二者的祖先相同
    62             {
    63                 if(dis[a]==dis[b]) flag=1;//且与祖先的性别关系相同,出现错误 
    64             }
    65             else//二者祖先不同
    66             {
    67                 fa[bb]=fa[aa];
    68                 dis[bb]=(dis[a]+1-dis[b])%2;
    69             }
    70         }
    71         if(k!=1) printf("
    ");//格式要求 
    72         printf("Scenario #%d:
    ",k);
    73         if(flag==1) printf("Suspicious bugs found!
    ");
    74         else printf("No suspicious bugs found!
    ");
    75     }
    76     
    77     return 0;
    78 }

    第二种:

    fa开两倍空间,fa[i+n]相当于i的对立集合,这种可能耗时会多一点吧

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <iostream>
     4 #include <string>
     5 #include <math.h>
     6 #include <algorithm>
     7 #include <vector>
     8 #include <stack>
     9 #include <queue>
    10 #include <set>
    11 #include <map>
    12 #include <sstream>
    13 const int INF=0x3f3f3f3f;
    14 typedef long long LL;
    15 const int mod=1e9+7;
    16 const int maxn=1e5+10;
    17 using namespace std;
    18 
    19 int fa[5005];
    20 void init(int n)
    21 {
    22     for(int i=0;i<=n;i++)
    23         fa[i]=i;
    24 }
    25 int Find(int x)
    26 {
    27     return x==fa[x]? x:fa[x]=Find(fa[x]);
    28 }
    29 void Union(int a,int b)
    30 {
    31     int aa=Find(a);
    32     int bb=Find(b);
    33     if(aa!=bb) fa[aa]=bb;
    34 }
    35 
    36 int main()
    37 {
    38     #ifdef DEBUG
    39     freopen("sample.txt","r",stdin);
    40     #endif
    41 //    ios_base::sync_with_stdio(false);
    42 //    cin.tie(NULL);
    43     
    44     int T;
    45     scanf("%d",&T);
    46     for(int k=1;k<=T;k++)
    47     {
    48         int n,m;
    49         scanf("%d %d",&n,&m);
    50         init(2*n);
    51         int flag=0;//flag=1表示找到了错误 
    52         for(int i=1;i<=m;i++)
    53         {
    54             int a,b;
    55             scanf("%d %d",&a,&b);
    56             if(flag) continue;
    57             int aa=Find(a);
    58             int bb=Find(b);
    59             if(aa==bb) flag=1;// 二者同属一个集合,性别相同 
    60             else//二者性别不同,不属于同一个集合 
    61             {
    62                 Union(a,b+n);//a和b的对立集合同属一个集合 
    63                 Union(a+n,b);//b和a的对立集合同属一个集合
    64             }
    65         }
    66         if(k!=1) printf("
    ");//格式要求 
    67         printf("Scenario #%d:
    ",k);
    68         if(flag==1) printf("Suspicious bugs found!
    ");
    69         else printf("No suspicious bugs found!
    ");
    70     }
    71     
    72     return 0;
    73 }

    -

  • 相关阅读:
    C sharp(C#)-小结
    安全开源工具清单
    pycharm中查看sqlite3数据库
    部署docker化的mobsf
    python处理文件、文件夹-小结
    windows上Python控制台乱码和处理
    自定义日志:记录Linux主机操作
    不是热点新闻的重大事件
    mybatis-04【小结】
    mybatis-03
  • 原文地址:https://www.cnblogs.com/jiamian/p/12262326.html
Copyright © 2020-2023  润新知