题目:
中文的就不说了~~~~
思路:
属于并查集的基础题,比较典型,可以把连通在一起的看成是一个点,假设一共有N个独立的点,那么就需要 N - 1 条边把他们连通起来,所以利用并查集算法,最后统计有多少个独立的集合,然后把这个数减去一便是我们所要的答案了~~~~
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <cctype> 7 #include <algorithm> 8 using namespace std; 9 const int MAXN = 1e3 + 3; 10 int pre[MAXN]; //保存的是父节点的值 11 bool root[MAXN]; //是否为根节点 12 13 int Find(int x) 14 { 15 int r = x; 16 while(pre[r] != r) 17 { 18 r = pre[r]; 19 } 20 int i = x,j; 21 while(pre[i] != r) 22 { 23 j = i; 24 i = pre[i]; 25 pre[j] = r; 26 } 27 return r; 28 } 29 30 void mix(int a,int b) 31 { 32 int x = Find(a); 33 int y = Find(b); 34 if(x > y) 35 { 36 pre[x] = y; 37 } 38 if(x < y) 39 { 40 pre[y] = x; 41 } 42 } 43 44 int main() 45 { 46 int M,N; 47 while(~scanf("%d",&M)&&M) 48 { 49 scanf("%d",&N); 50 for(int i = 1; i <= M; i++) 51 { 52 pre[i] = i; 53 root[i] = false; 54 } 55 while(N--) 56 { 57 int a,b; 58 scanf("%d%d",&a,&b); 59 mix(a,b); 60 } 61 for(int i = 1; i <= M; i++) 62 { 63 if(pre[i] == i) 64 root[i] = true; 65 } 66 int ans = 0; 67 for(int i = 1; i <= M; i++) 68 { 69 if(root[i]) ans ++; 70 } 71 printf("%d ",ans-1); 72 } 73 return 0; 74 }