物品分类
题目链接: http://hihocoder.com/contest/offers56/problem/3
解题思路: 对于关系R1,利用并查集维护,对于关系R2利用set维护,其他的是R3。需要在并查集合并的时候更新关系R2的set。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 const int MAXN = 200010; 6 const LL MON7 = 1e9+7; 7 8 int f[MAXN]; 9 set<int> g[MAXN]; 10 int n,m; 11 12 13 int find(int x) 14 { 15 if (x==f[x]) return x; 16 return f[x]=find(f[x]); 17 } 18 19 void merge(int a,int b) 20 { 21 if (g[a].size()<g[b].size()) swap(a,b); 22 for (auto &x:g[b]) g[a].insert(find(x)); 23 f[b]=a; 24 } 25 26 27 int main() 28 { 29 #ifndef ONLINE_JUDGE 30 freopen("test.txt","r",stdin); 31 #endif // ONLINE_JUDGE 32 scanf("%d%d",&n,&m); 33 for (int i=0;i<=n+1;++i) f[i]=i; 34 int a,b,i,j,k; 35 char op[5]; 36 while(m--) { 37 scanf("%s%d%d",op,&i,&j); 38 a=find(i); 39 b=find(j); 40 if (op[0]=='R') { 41 scanf("%d",&k); 42 if (k==1) {if(a!=b) merge(a,b);} 43 else { 44 g[a].insert(b);g[b].insert(a); 45 } 46 } else { 47 // printf("u=%d fu=%d v=%d fv=%d\n", u, fu, v, fv); 48 if (a==b) printf("1\n"); 49 else { 50 int flags=0; 51 if (g[a].size()<=g[b].size()) { 52 for (auto x:g[a]) if (find(x)==b) {flags=1;break;} 53 } 54 else { 55 for (auto x:g[b]) if (find(x)==a) {flags=1;break;} 56 } 57 if (flags) printf("2\n");1 58 else printf("3\n"); 59 } 60 } 61 } 62 return 0; 63 }