1. 程式人生 > ><九度 OJ>題目1012:暢通project

<九度 OJ>題目1012:暢通project

數組下標 find cout set href col 設置 data []

題目描寫敘述:

某省調查城鎮交通狀況,得到現有城鎮道路統計表。表中列出了每條道路直接連通的城鎮。省政府“暢通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


&lt;九度 OJ&gt;題目1012:暢通project