POJ-2492 A Bug's Life(种类并查集)
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("\n");//格式要求 72 printf("Scenario #%d:\n",k); 73 if(flag==1) printf("Suspicious bugs found!\n"); 74 else printf("No suspicious bugs found!\n"); 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("\n");//格式要求 67 printf("Scenario #%d:\n",k); 68 if(flag==1) printf("Suspicious bugs found!\n"); 69 else printf("No suspicious bugs found!\n"); 70 } 71 72 return 0; 73 }
-