1. 程式人生 > >種類並查集

種類並查集

poj str 給定 fin problem div style find nod

  一般的並查集是維護屬於同一種類的元素,對於屬於不同種類的元素之間的關系沒有記錄。種類並查集就是同一集合中的元素是已經確定關系的(是否屬於同一種類),然後加一個group數組,記錄一下孩子和父親是否屬於同一種類,遞推稍稍改一下就可以了。

poj1703:http://poj.org/problem?id=1703

題目大意:有n個罪犯,兩個幫派,已知其中若幹對兩者屬於不同幫派,求給定的罪犯是否屬於同一幫派。

需要註意,給的兩個罪犯可能已經在同一個集合裏了,需要處理一下,不然就無限遞歸了。。。

 1 #include<iostream>
 2 #include<cstring>
 3
#include<cstdio> 4 using namespace std; 5 const int maxn=1e5+5; 6 int p[maxn],group[maxn],n,m; 7 int Find(int x){ 8 if(p[x]==x)return x; 9 int t=Find(p[x]); 10 group[x]=group[x]==group[p[x]]?1:0; 11 return p[x]=t; 12 } 13 void Unit(int a,int b){ 14 int x=Find(a),y=Find(b);
15 if(x==y)return; 16 p[x]=b; 17 group[x]=1^group[a]; 18 } 19 int Is_same(int a,int b){ 20 int x=Find(a),y=Find(b); 21 if(x!=y)return -1; 22 return group[a]==group[b]; 23 } 24 int main(){ 25 int t,a,b; 26 char c; 27 scanf("%d",&t); 28 while(t--){ 29 scanf("
\n%d%d",&n,&m); 30 for(int i=0;i<n;i++){p[i]=i;group[i]=1;} 31 for(int i=0;i<m;i++){ 32 scanf("\n%c%d%d",&c,&a,&b); 33 a--;b--; 34 if(c==D){ 35 Unit(a,b); 36 }else{ 37 int t=Is_same(a,b); 38 if(t==-1)printf("Not sure yet.\n"); 39 else if(t==0)printf("In different gangs.\n"); 40 else if(t==1)printf("In the same gang.\n"); 41 } 42 } 43 } 44 return 0; 45 }

51nod 1204 Parity

技術分享

分析:記前k個的和的奇偶性為f[k],若[a,b]和為偶數,則f[a]==f[b],否則f[a]!=f[b],然後用種類並查集維護一下就可以了。

 1 #include<iostream>
 2 #include<string>
 3 using namespace std;
 4 const int maxn=100005;
 5 int p[maxn],group[maxn],n,q;
 6 int Find(int x){
 7     if(p[x]==x)return x;
 8     Find(p[x]);
 9     group[x]=group[p[x]]==group[x]?1:0;
10     p[x]=Find(p[x]);
11     return p[x];
12 }
13 int main(){
14     cin>>n>>q;
15     for(int i=0;i<=n;i++){p[i]=i;group[i]=1;}
16     int a,b,ans=-1;
17     char s[10];
18     for(int i=0;i<q;i++){
19         cin>>a>>b>>s;
20         int x=Find(a-1),y=Find(b);
21         if(s[0]==e){
22             if(x==y&&group[a-1]!=group[b]&&ans==-1)
23                 ans=i+1;
24             if(x!=y){
25                 p[x]=y;
26                 group[x]=group[a-1]==group[b]?1:0;
27             }
28         }else{
29             if(x==y&&group[a-1]==group[b]&&ans==-1)
30                 ans=i+1;
31             if(x!=y){
32                 p[x]=y;
33                 group[x]=group[a-1]==group[b]?0:1;
34             }
35         }
36     }
37     cout<<ans<<endl;
38     return 0;
39 }

種類並查集