标签:
乱世天下,诸侯割据。每个诸侯王都有一片自己的领土。但是不是所有的诸侯王都是安分守己的,实力强大的诸侯国会设法吞并那些实力弱的,让自己的领土面积不断扩大。而实力弱的诸侯王为了不让自己的领土被吞并,他会联合一些其他同样弱小的诸侯国,组成联盟(联盟不止一个),来共同抵抗那些强大的诸侯国。 强大的诸侯国为了瓦解这些联盟,派出了最优秀的间谍来离间他们,使一些诸侯国退出联盟。最开始,每个诸侯国是一个联盟。
有两种操作
1、U x y 表示x和y在同一个联盟。(0≤x,y<n)
2、D x 表示x退出联盟。
5 7 U 0 1 U 1 2 U 0 3 D 0 U 1 4 D 2 U 0 2 10 1 U 0 9
Case #1: 2 Case #2: 9
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 using namespace std; 5 int father[100010], set[100010 * 2], vis[100010 * 2]; 6 int n, m; 7 void init() 8 { 9 for(int i = 0; i < n; i++) 10 { 11 father[i] = i; 12 set[i] = i; 13 } 14 } 15 int find(int a) 16 { 17 int r, j, k; 18 r = a; 19 while(r != set[r]) 20 r = set[r]; 21 j = a; 22 while(j != r) 23 { 24 k = set[j]; 25 set[j] = r; 26 j = k; 27 } 28 return r; 29 } 30 void mercy(int a, int b) 31 { 32 int q = find(a); 33 int p = find(b); 34 if(q != p) 35 set[q] = p; 36 } 37 int main() 38 { 39 int temp = 1; 40 while(~scanf("%d %d", &n, &m)) 41 { 42 init(); 43 int dis = n; //虚点; 44 for(int i = 0; i < m; i++) 45 { 46 char str[2]; 47 scanf("%s", str); 48 if(str[0] == ‘U‘) 49 { 50 int a, b; 51 scanf("%d %d", &a, &b); 52 mercy(father[a], father[b]); 53 } 54 else 55 { 56 int c; 57 scanf("%d", &c); 58 father[c] = dis; 59 set[dis] = dis; 60 dis++; 61 } 62 } 63 int ans = 0; 64 memset(vis, 0, sizeof(vis)); 65 for(int i = 0; i < n; i++) 66 { 67 if(!vis[find(father[i])]) 68 { 69 //printf("%d %d %d\n", set[i], father[i], find(father[i])); 70 vis[find(father[i])] = 1; 71 ans++; 72 } 73 } 74 printf("Case #%d: %d\n", temp++, ans); 75 } 76 return 0; 77 }
标签:
原文地址:http://www.cnblogs.com/fengshun/p/4732896.html