Information
- ID
- 1258
- Time
- 1000ms
- Memory
- 128MiB
- Difficulty
- 5
- Tags
- # Submissions
- 112
- Accepted
- 46
- Uploaded By
采用并查集的思想:我们只需要计算出有几个家族,家族数减一就是答案
#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");
}
}
#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;
}
并查集模板 需要判断集合数
#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条边
}
}
By signing up a 追梦算法网 universal account, you can submit code and join discussions in all online judging services provided by us.