圖論_查並集
例5.1 暢通工程 (1012)
- 題目描述:某省調查城鎮交通狀況,得到現有城鎮道路統計表,表中列出了每條道路直接連通的城鎮。省政府“暢通工程”的目標是使全省任何兩個城鎮間都可以實現交通(但不一定有直接的道路相連,只要互相間接通過道路可達即可)。問最少還需要建設多少條道路?
- 輸入:測試輸入包含若幹測試用例。每個測試用例的第1行給出兩個正整數,分別是城鎮數目N ( < 1000 )和道路數目M;隨後的M行對應M條道路,每行給出一對正整數,分別是該條道路直接連通的兩個城鎮的編號。為簡單起見,城鎮從1到N編號。
輸出:對每個測試用例,在1行裏輸出最少還需要建設的道路數目。
樣例輸入: 4 2 1 3 4 3 3 3 1 2 1 3 2 3 5 2 1 2 3 5 999 0 0 樣例輸出: 1 0 2 998
#include<stdio.h> using namespace std; #define N 1000 int Tree[N]; int findRoot(int x){ if(Tree[x]==-1) return x; else{ int tmp=findRoot(Tree[x]); Tree[x]=tmp; return tmp; } } int main(){ int n,m; while(scanf("%d",&n)!=EOF&&n!=0){ scanf("%d",&m); for(int i=1;i<=n;i++) Tree[i]=-1; while(m--){ int a,b; scanf("%d%d",&a,&b); a=findRoot(a); b=findRoot(b); if(a!=b) Tree[a]=b; } int ans=0; for(int i=1;i<=n;i++){if(Tree[i]==-1) ans++; } printf("%d\n",ans-1); } return 0; }
例5.2 More is better (1044)
題目描述:Mr Wang wants some boys to help him with a project. Because the project is rather complex, the more boys come, the better it will be. Of course there are certain requirements.Mr Wang selected a room big enough to hold the boys. The boy who are not been chosen has to leave the room immediately. There are 10000000 boys in the room numbered from 1 to 10000000 at the very beginning. After Mr Wang‘s selection any two of them who are still in this room should be friends (direct or indirect), or there is only one boy left. Given all the direct friend-pairs, you should decide the best way.
- 輸入:The first line of the input contains an integer n (0 ≤ n ≤ 100 000) - the number of direct friend-pairs. The following n lines each contains a pair of numbers A and B separated by a single space that suggests A and B are direct friends. (A ≠ B, 1 ≤ A, B ≤ 10000000)
輸出:The output in one line contains exactly one integer equals to the maximum number of boys Mr Wang may keep.
題目大意:有10000000個小朋友,他們之中有N對好朋友,且朋友的關系具有傳遞性,要求我們找出一個最大(人數最多)的集合,該集合中任意兩人之間都是朋友或者該集合中只有一個人,輸出該最大人數。
樣例輸入: 4 1 2 3 4 5 6 1 6 4 1 2 3 4 5 6 7 8 樣例輸出: 4 2
#include <stdio.h> const int maxm = 10000002; int parent[maxm]; int num[maxm]; int n; int i; int findParent(int f) { while(parent[f] != f){ f = parent[f]; } return f; } void unionTwo(int f, int t) { int a = findParent(f); int b = findParent(t); if (a == b) return; if (a > b) { parent[a] = b; } else { parent[b] = a; } } int max(int a, int b){ return a > b ? a : b; } int main(){ while(scanf("%d",&n) != EOF){ for(i = 1; i < maxm; i++){ parent[i] = i; num[i] = 1; } for(i = 0 ; i < n ; i++){ int a, b; scanf("%d%d",&a,&b); unionTwo(a,b); } if(n == 1){ printf("%d\n",2); continue; } int maxNum = 1; for (i = 1; i < maxm; i++) { maxNum = max(++num[findParent(i)] , maxNum); } printf("%d\n",maxNum - 1); } return 0; }
圖論_查並集