<九度 OJ>題目1012:暢通project
- 題目描寫敘述:
-
某省調查城鎮交通狀況,得到現有城鎮道路統計表。表中列出了每條道路直接連通的城鎮。省政府“暢通project”的目標是使全省不論什麽兩個城鎮間都能夠實現交通(但不一定有直接的道路相連,僅僅要互相間接通過道路可達就可以)。
問最少還須要建設多少條道路?
- 輸入:
-
測試輸入包括若幹測試用例。每一個測試用例的第1行給出兩個正整數。各自是城鎮數目N ( < 1000 )和道路數目M;隨後的M行相應M條道路,每行給出一對正整數,各自是該條道路直接連通的兩個城鎮的編號。為簡單起見,城鎮從1到N編號。
註意:兩個城市之間能夠有多條道路相通,也就是說
3 3
1 2
1 2
2 1
這樣的輸入也是合法的
當N為0時,輸入結束,該用例不被處理。
- 輸出:
-
對每一個測試用例,在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
分析:
並查集的簡單應用,用並查集聯立m對已經聯通的城鎮。聯立後在一個集合的點將僅僅有一個公共的最高祖先。最後查看孤立城鎮有多少個就可以。
#include "vector" #include "string" #include "algorithm" #include <iostream> #include "stack" #include <cmath> #include <set> using namespace std; class UFSet { public: UFSet(int nsize) { size = nsize; parent = new int[size]; }; ~UFSet() { delete[] parent; parent = NULL; }; void makeSet(int n);////初始化每個元素的祖先為自身 int findSet(int x);//找到元素x的祖先元素parent[x] void unionSet(int a, int b);//若兩個元素的祖先不同,則將x元素的祖先設置為y元素的祖先 int getSets(int n);//獲取獨立的集合數量 private: int *parent;//存放祖先節點,比如x=parent[i]。元素i的祖先節點為元素x int size; }; void UFSet::makeSet(int n) //初始化 { //初始化每個元素都各自為一個獨立的集合。其祖先均設定為自身 for (size_t i = 1; i <= n; i++) parent[i] = i; } int UFSet::findSet(int x) { //找到元素所在的集合。也就是找到自己的最高的祖先。 //這也是推斷兩個元素是否在同一個集合中的主要根據。 if (parent[x] == x)//遞歸截止條件(最高祖先的祖先是其自身) return x; parent[x] = findSet(parent[x]);//遞歸,終於找到x的最高祖先。而且沿途找到全部的最高祖先 return parent[x]; } void UFSet::unionSet(int x, int y) { //將x和y所在的集合進行合並,利用findSet()推斷x和y所在的集合是否同樣, //假設不同,則要把當中一個元素的祖先指向還有一個元素的祖先。int ux = findSet(x);//獲取節點x的祖先 int uy = findSet(y); if (ux != uy) parent[ux] = uy; } int UFSet::getSets(int n) { int count = 0; for (int i = 1; i <= n; i++) {//假設存在某一個節點的祖先是自身說明他是孤立的 if (parent[i] == i) count++; } return count; } int main() { int m, n; while (cin >> n >> m) { UFSet uset(10000); uset.makeSet(n);//初始化 //接收m對已經聯通的城鎮 int x = 0, y = 0; for (int i = 0; i<m; i++) { cin >> x >> y;//註:這裏數組下標位置代表城鎮編號 uset.unionSet(x, y); } cout << uset.getSets(n)-1 << endl; } return 0; } /************************************************************** Problem: 1012 User: EbowTang Language: C++ Result: Accepted Time:10 ms Memory:1520 kb ****************************************************************/
註:本博文為EbowTang原創,興許可能繼續更新本文。
假設轉載。請務必復制本條信息!
原文地址:http://blog.csdn.net/ebowtang/article/details/50515067
原作者博客:http://blog.csdn.net/ebowtang
<九度 OJ>題目1012:暢通project