5月14日

poj1703

题意:有两个帮派,给定一些操作,A a b判断a与b是否在同一帮派,D a b将a与b加入不同帮派

分析:非常好的并查集题目,用两倍的并查集分别来表示两个帮派,当进行D操作时,将a与b+n,a+n与b分别加同一帮派,A操作时进行判断,same(a,b)表示a与b在同一帮派,same(a,b+n)表示a与b在不同帮派,否则不能确定

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <string>
 5 #include <vector>
 6 #include <algorithm>
 7 #include <set>
 8 #include <map>
 9 #include <bitset>
10 #include <cmath>
11 #include <queue>
12 #include <stack>
13 using namespace std;
14 const int maxn=100010;
15 int par[maxn*2],rankl[maxn*2];
16 void init(int n){
17     for(int i=0;i<n;i++){
18         par[i]=i;
19         rankl[i]=0;
20     }
21 }
22 
23 int findl(int x){
24     if(par[x]==x)  return x;
25     else{
26         return par[x]=findl(par[x]);
27     }
28 }
29 
30 void unite(int x,int y){
31     x=findl(x);
32     y=findl(y);
33     if(x==y)  return;
34     if(rankl[x]<rankl[y]){
35         par[x]=y;
36     }else{
37         par[y]=x;
38         if(rankl[x]==rankl[y])  rankl[x]++;
39     }
40 }
41 
42 bool same(int x,int y ){
43     return findl(x)==findl(y);
44 }
45 
46 int main()
47 {
48     int t;
49     cin>>t;
50     while(t--)
51     {
52         int n,m;
53         cin>>n>>m;
54         init(n*2);
55         getchar();
56         char s;
57         int a,b;
58         while(m--){
59             scanf("%c%d%d%*c",&s,&a,&b);
60             if(s=='A'){
61                 if(same(a,b)){
62                     cout<<"In the same gang."<<endl;
63                 }
64                 else if(same(a,b+n)){
65                     cout<<"In different gangs."<<endl;
66                 }else{
67                     cout<<"Not sure yet."<<endl;
68                 }
69             }else{
70                 unite(a,b+n);
71                 unite(a+n,b);
72             }
73         }
74     }
75     
76     return 0;
77 }
View Code

 AOJ2170

题意:给定一颗树,同时给出n个结点,以及每个结点的父结点,给出Q个操作,M a表示将a结点点亮,Q a表示找到与a相距最近的结点,问最后所有Q操作找到的结点之和

分析:用并查集维护,只不过结点变成了当前结点的父结点,注意会爆int

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <string>
 5 #include <vector>
 6 #include <algorithm>
 7 #include <set>
 8 #include <map>
 9 #include <bitset>
10 #include <cmath>
11 #include <queue>
12 #include <stack>
13 using namespace std;
14 const int maxn=100010;
15 typedef struct p
16 {
17     int par,vis;
18 }p;
19 p s[maxn];
20 
21 void init(int n){
22     for(int i=1;i<=n;i++){
23         s[i].par=i;
24         s[i].vis=0;
25     }
26 }
27 int main()
28 {
29     int n,q;
30     while(cin>>n>>q)
31     {
32         if(n+q==0)  break;
33         init(n);
34         s[1].vis=1;
35         for(int i=2;i<=n;i++){
36             int x;
37             scanf("%d",&x);
38             s[i].par=x;
39         }
40         getchar();
41         long long sum=0;
42         while(q--){
43             char sh;
44             int a;
45             scanf("%c%d%*c",&sh,&a);
46             if(sh=='M'){
47                 s[a].vis=1;
48             }else{
49                 if(s[a].vis==1){
50                     sum+=a;
51                 }else{
52                     while(true){
53                         if(s[a].vis==1){
54                             sum+=a;  break;
55                         }else{
56                             a=s[a].par;
57                         }
58                     }
59                 }
60             }
61         }
62         cout<<sum<<endl;
63     }
64     return 0;
65 }
View Code

 

posted @ 2016-05-16 19:48  wolf940509  阅读(179)  评论(0)    收藏  举报