标签:while name 整数 tput pac 关系 queue lang 并查集
Input
Output
Sample Input
100 7 1 101 1 2 1 2 2 2 3 2 3 3 1 1 3 2 3 1 1 5 5
Sample Output
3
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 using namespace std; 10 const int MAX=5e4+5; 11 int par[MAX*3],rankk[MAX*3]; 12 void init(int n) 13 { 14 for(int i=0;i<n;i++) 15 { 16 par[i]=i; 17 rankk[i]=0; 18 } 19 } 20 int find(int x) 21 { 22 if(par[x]==x) 23 return x; 24 else 25 return par[x]=find(par[x]); 26 } 27 void unite(int x,int y) 28 { 29 x=find(x); 30 y=find(y); 31 if(x==y) 32 return; 33 if(rankk[x]<rankk[y]) 34 par[x]=y; 35 else 36 { 37 par[y]=x; 38 if(rankk[x]==rankk[y]) 39 rankk[x]++; 40 } 41 } 42 bool same(int x,int y) 43 { 44 return find(x)==find(y); 45 } 46 int n,k; 47 int an; 48 int opt,a,b; 49 int main() 50 { 51 scanf("%d%d",&n,&k); 52 init(3*n); 53 while(k--) 54 { 55 scanf("%d%d%d",&opt,&a,&b); 56 a--;b--; 57 if(a<0||b<0||a>=n||b>=n||(opt==2&&a==b)) 58 { 59 an++;continue; 60 } 61 if(opt==1) 62 { 63 if(same(a,b+2*n)||same(a+2*n,b)) 64 { 65 an++; 66 continue; 67 } 68 else 69 { 70 unite(a,b); 71 unite(a+n,b+n); 72 unite(a+2*n,b+2*n); 73 } 74 } 75 else 76 { 77 if(same(a,b)||same(a,b+2*n)) 78 { 79 an++;continue; 80 } 81 else 82 { 83 unite(a+2*n,b); 84 unite(a+n,b+2*n); 85 unite(a,b+n); 86 } 87 } 88 } 89 printf("%d\n",an); 90 }
用x,x+n,x+2*n,分别表示元素在A、B、C集合中。某两个元素在同一个树中意味他们同时发生或同时不发生。向并查集中加入元素时要把各种情况全部加入,查询是否合法时只需查询1种不行的即可(指吃与被吃的关系)
标签:while name 整数 tput pac 关系 queue lang 并查集
原文地址:http://www.cnblogs.com/quintessence/p/6572598.html