3 solutions
-
1
采用并查集的思想:我们只需要计算出有几个家族,家族数减一就是答案
#include <bits/stdc++.h> using namespace std; int w[1007]; int find(int x){ if(w[x]==x) return x; else return w[x]=find(w[x]); } int main(){ int n,m,x,y; while(~scanf("%d%d",&n,&m)&n){ for(int i=1;i<=n;i++) w[i]=i; for(int i=0;i<m;i++){ scanf("%d%d",&x,&y); w[find(x)]=find(y); } int sum=0; for(int i=1;i<=n;i++){ if(i==w[i]) sum++; } cout<<sum-1; printf("\n"); } }
-
0
#include<bits/stdc++.h> using namespace std; const int N = 1e3+7; int nums[N]; // 使用并查集思想,使用并查集计算出孤立的点n(孤立的点即自己是自己的祖先),答案为n-1 void init(){ for (int i = 1; i < N; i++) { nums[i] = i; } } int find(int x) { while (x != nums[x]) { x = nums[x]; } return x; } void merge(int a, int b){ int af = find(a); int bf = find(b); if (af != bf) nums[bf] = af; } int main (){ int n, m; while (~ scanf("%d %d", &n, &m) & n) { init(); // 使孤立的点连接起来 for (int i = 1; i <= m; i++) { int a, b; scanf("%d %d", &a, &b); merge(a, b); } // 计算连接后,一共有n个部分,答案为n-1 int sum = 0; for (int i = 1; i <= n; i++) { if (nums[i] == i) sum++; } printf("%d\n", sum - 1); } return 0; }
-
0
并查集模板 需要判断集合数
#include <bits/stdc++.h> using namespace std; const int N=1e3+7; int fa[N]; int x,y,u,v; void init(){//初始化,每个数看成一个集合 for(int i=1;i<=N;i++) fa[i]=i; } int find(int x){ //这里不能用路劲压缩 if(x==fa[x]) return x; else return find(fa[x]); } void merge(int x,int y)//合并 { u=find(x); v=find(y); if(u!=v) fa[u]=v; } int main(){ int n,m,x,y; while(~scanf("%d%d",&n,&m)&n){ init(); //注意位置 for(int i=0;i<m;i++){ scanf("%d%d",&x,&y); merge(x,y); } int sum=0; for(int i=1;i<=n;i++){ //已经连通的村庄整体算一个集合 if(i==fa[i]) sum++;//!!! } printf("%d\n",sum-1);//n个集合可以看成n个点,连通至少需要n-1条边 } }
- 1
Information
- ID
- 1258
- Time
- 1000ms
- Memory
- 128MiB
- Difficulty
- 5
- Tags
- # Submissions
- 110
- Accepted
- 44
- Uploaded By