Ubiquitous Religions
Ubiquitous Religions
题面翻译
题目简述
有一个 \(n\) 个点,\(m\) 条边的无向图,求这个图有多少个连通块。
输入格式
本题多组数据。
每组数据的第一行为 \(n\) 和 \(m\)。
接下来 \(m\) 行,每一行两个值 \(x,y\),描述一条由 \(x\) 到 \(y\) 的无向边。
输入的结束为 \(0\ 0\)。
输出格式
对于每一组数据,输出一行 Case i: ans,其中 \(i\) 表示目前是第 \(i\) 组数据,\(ans\) 表示第 \(i\) 组数据的图的连通块个数。
说明/提示
\(0<n\le 5\times 10^4\),\(0\le m\le \frac{n\times (n-1)}{2}\)。
题目描述

输入格式

输出格式

样例 #1
样例输入 #1
10 9
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
10 4
2 3
4 5
4 8
5 8
0 0
样例输出 #1
Case 1: 1
Case 2: 7
分析
这道判断连通块问题,由于是通过输入无向边,很自然可以想到使用并查集进行操作
#include <bits/stdc++.h>
using namespace std;
const int N = 3e5;
int s[N];
int height[N];
void init_set(){
for(int i = 1;i <= N;i++){
s[i] = i;height[i] = 0;
}
}
int find_set(int x){
if(x!=s[x])s[x] = find_set(s[x]);
return s[x];
}
void merge_set(int x,int y){
x = find_set(x);
y = find_set(y);
if(height[x] == height[y]){
height[x] = height[x] + 1;
s[y] = x;
}
else{
if(height[x]<height[y]) s[x] = y;
else
s[y] = x;
}
}
int main(){
int n,m,cot=0;
while(cin>>n>>m){
++cot;
int ans=0;
if(m==0&&n==0)break;
init_set();
while(m--){
int a,b;cin>>a>>b;
merge_set(a,b);
}
for(int i = 1;i<=n;i++)
if(s[i]==i)ans++;
cout<<"Case "<<cot<<": "<<ans<<endl;
}
return 0;
}

浙公网安备 33010602011771号