poj1703 Find them, Catch them(带权并查集)
题目链接
http://poj.org/problem?id=1703
题意
有两个帮派:龙帮和蛇帮,两个帮派共有n个人(编号1~n),输入m组数据,每组数据为D [a][b]或A [a][b],D[a][b]表示a,b属于不同的帮派,A [a][b]则让我们判断a,b是否属于一个帮派,根据判断的结果进行相应的输出。
思路
这题和poj2492很像,使用并查集解决,方法我已在poj2492的题解中写出,这里不再赘述。
代码
1 #include <cstdio> 2 using namespace std; 3 4 const int N = 100000 + 10; 5 int p[N]; 6 int r[N]; 7 8 void make_set(int n) 9 { 10 for (int i = 1;i <= n;i++) 11 { 12 p[i] = -1; 13 r[i] = 0; 14 } 15 } 16 17 int find_root(int x) 18 { 19 if (p[x] == -1) 20 return x; 21 22 int t = p[x]; 23 p[x] = find_root(p[x]); 24 r[x] = (r[x] + r[t]) % 2; 25 return p[x]; 26 } 27 28 void union_set(int a, int b) 29 { 30 int ra = find_root(a); 31 int rb = find_root(b); 32 33 if (ra != rb) 34 { 35 p[ra] = rb; 36 r[ra] = (r[a] + r[b] + 1) % 2; 37 } 38 } 39 40 int main() 41 { 42 //freopen("poj1703.txt", "r", stdin); 43 int t; 44 scanf("%d", &t); 45 while (t--) 46 { 47 int n, m; 48 scanf("%d%d", &n, &m); 49 make_set(n); 50 char c; 51 int a, b; 52 for (int i = 0;i < m;i++) 53 { 54 getchar(); 55 scanf("%c%d%d", &c, &a, &b); 56 if (c == 'A') 57 { 58 if (find_root(a) == find_root(b)) //a,b在一个集合里 59 { 60 if (r[a] == r[b]) //a,b为同一帮派 61 puts("In the same gang."); 62 else puts("In different gangs."); //a,b为不同帮派 63 } 64 else puts("Not sure yet."); //a,b不再同一集合里,故不确定 65 } 66 else union_set(a, b); 67 } 68 } 69 return 0; 70 }
注意点
1、函数union_set要写成这样:
//正确写法 void union_set(int a, int b) { int ra = find_root(a); int rb = find_root(b); if (ra != rb) { p[ra] = rb; r[ra] = (r[a] + r[b] + 1) % 2; } }
写成如下形式会MLE:
//错误写法,MLE void union_set(int a, int b) { int ra = find_root(a); int rb = find_root(b); p[ra] = rb; r[ra] = (r[a] + r[b] + 1) % 2; }
2、使用scanf输入。
相似题目
1、poj2492
本站使用「CC BY-NC-SA」创作共享协议,转载请在文章明显位置注明作者及出处。