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}\)

题目描述

PDF

输入格式

输出格式

样例 #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;
}
posted @ 2023-08-30 20:25  LongDz  阅读(19)  评论(0)    收藏  举报