幷查集拓展

拓展就是說並不是很明顯的可以套幷查集的模板,或者是要拐個彎的,或者幷查集優化的之類...

poj 1703.Find them, Catch them

這題就是兩個團伙,輸入A代表判斷這兩個人是否一個團伙,不同團伙,或者不確定;而輸入D則表示兩個人不是一個團伙;

如果用幷查集的話,我們一般是合併同一個團伙的,但是我一開始想的是反其道而行,合併不同團伙的,這是可以的,然後再

用0和1標記一下是否是一個團伙,但是想的很亂,搞了好久沒做出來,結果...發現了一種很神奇的方法,佩服佩服:

 

因為是兩個團伙,所以我們把數組擴展一下,比如四個人1,2,3,4,我們把編號擴展成1,2,3,4,5,6,7,8;當輸入1,2不是同一個團伙,

我們就是1+4=5和2作為一個團伙(5,2),1和2+4=6作為一個團伙(1,6);當再輸入2,3不是一個團伙,那麼(2,7), (6,3),這樣我們

就找到了(1,6)和(6,3)可以合併到一起,表示(1,3)是一伙的!太巧妙了,怎麼想得到!

 1 // poj 1703.Find them, Catch them
 2 // 并查集 高级
 3 // references:
 4 // http://www.hankcs.com/program/cpp/poj-1703-find-them-catch-them.html 太巧妙了 
 5 #include <iostream>
 6 #include <cstdio>
 7 #include <cstring>
 8 #include <algorithm>
 9 
10 using namespace std;
11 
12 const int N = 200105;
13 
14 int p[N];
15 int n, m;
16 
17 void init()
18 {
19     for(int i=0; i<N; i++)
20     {
21         p[i] = -1;
22     }
23 }
24 
25 int find(int x)
26 {
27     return p[x] == -1 ? x : p[x] = find(p[x]);
28 }
29 
30 void union_set(int u, int v)
31 {
32     int x = find(u);
33     int y = find(v);
34     if(x != y)
35     {
36         p[x] = y;
37     }
38 }
39 
40 int main()
41 {
42     int t;
43     scanf("%d", &t);
44     while(t--)
45     {
46         init();
47         scanf("%d%d", &n, &m);
48         for(int i=0; i<m; i++)
49         {
50             getchar();
51             int u, v;
52             char s;
53             scanf("%c%d%d", &s, &u, &v);
54             if(s == 'A')
55             {
56                 if(find(u) == find(v))
57                 {
58                     printf("In the same gang.\n");
59                 }
60                 else if(find(u) == find(v + n) || find(u + n) == find(v))
61                 {
62                     printf("In different gangs.\n");
63                 }
64                 else
65                     printf("Not sure yet.\n");        
66             }
67             else
68             {
69                 union_set(u, v + n);
70                 union_set(u + n, v);
71             }
72         }
73     }
74     return 0;
75 } 

 

最後要注意scanf的緩衝區的問題啊啊啊...輸入%c的時候,注意回車要getchar()掉!!!

posted @ 2015-08-13 15:08  dominjune  阅读(128)  评论(0编辑  收藏  举报