1. 程式人生 > >演算法-並查集-加邊無向圖

演算法-並查集-加邊無向圖

題目描述:給你一個 n 個點,m 條邊的無向圖,求至少要在這個的基礎上加多少條無向邊使得任意兩個點可達~ 

輸入描述:第一行兩個正整數 n 和 m 。 接下來的m行中,每行兩個正整數 i 、 j ,表示點i與點j之間有一條無向道路。

輸出描述:輸出一個整數,表示答案

例 :

輸入

4 2 

1 2 
3 4

輸出:1

備註:對於100%的資料,有n,m<=100000。

#include<iostream>
#include<cstdio>
int pre[100000];//根據題目的資料規模 
using namespace std;
//並查集 --加邊無向圖 
//若pre[3]=7;那麼視為3的上級是7 下標不可重複,值可重複,對應一個父節點可以對應多個子節點 
void init(int pre[],int n){//初始化自己是自己的代表元 
    for(int i=1;i<=n;i++){
        pre[i]=i;
    }
}
int find(int x) {
    int r=x;
    while(pre[r]!=r){//自己不是代表元 
        r=pre[r]; //讓自己的上級再去找上級 
    }
    return r;
}

int main(){
    int n,m ,p1,p2,i,total,f1,f2;
    scanf("%d %d",&n,&m);//正整數已經確保n!=0 
    init(pre,n);
    total=n-1;
    while(m--){
        scanf("%d %d",&p1,&p2);
        f1=find(p1);
        f2=find(p2);
        if(f1!=f2){
            pre[f1]=f2;
            total--;
        }
    }
    printf("%d\n",total);

    return 0;
}