物品分类

题目链接: 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 }

 

posted @ 2018-04-22 19:17  只会一点暴力  阅读(261)  评论(0编辑  收藏  举报