1. 程式人生 > 其它 >[演算法設計與分析] 村村通 (並查集)

[演算法設計與分析] 村村通 (並查集)

luogu P1536

並查集板子題

 1 //
 2 //  main.cpp
 3 //  村村通
 4 //
 5 //  Created by sylvia on 2021/10/30.
 6 //  Copyright © 2021 apple. All rights reserved.
 7 //
 8 /*
 9  並查集板子題
10  建立好並查集後只需要列舉每個點,如果點的父親是自己就把ans+1
11  最後輸出的ans-1即可
12  實質是搜尋有多少不聯通的塊
13 */
14 #include <iostream>
15 #include <stdio.h>
16 #include <math.h>
17
#include <algorithm> 18 #include <string.h> 19 using namespace std; 20 #define M 1000+5 21 22 23 int V,E; //頂點數與邊數 24 int father[M],rankk[M]; 25 int u,v,ans=0; 26 void init(int n){//並查集初始化 27 for (int i=0;i<n;i++){ 28 father[i]=i; 29 rankk[i]=0; 30 } 31 } 32 int find(int
x){ 33 int j,k,r; 34 r=x; 35 while (r!=father[r]) r=father[r]; 36 k=x; 37 while (k!=r){ 38 j=father[k]; 39 father[k]=r; 40 k=j; 41 } 42 return r; 43 } 44 void unite(int x,int y){ //合併集合 45 x=find(x); 46 y=find(y); 47 if(x==y) return; 48 if
(rankk[x]<rankk[y]) father[x]=y; 49 else { 50 father[y]=x; 51 if(rankk[x]==rankk[y]) rankk[x]++; 52 } 53 } 54 int same(int x,int y){ //判斷是否在一個集合 55 return find(x)==find(y); 56 } 57 58 59 int main(){ 60 while ((cin>>V>>E)&&(V!=0)){ 61 ans=0; 62 init(V); 63 for (int i=0;i<E;i++){ 64 cin>>u>>v; 65 unite(u-1,v-1); 66 } 67 for (int i=0;i<V;i++) 68 if(father[i]==i) ans++; 69 cout<<ans-1<<endl; 70 } 71 return 0; 72 }