HDU1232 暢通工程 並查集入門

來源:互聯網
上載者:User


題目:

某省調查城鎮交通狀況,得到現有城鎮道路統計表,表中列出了每條道路直接連通的城鎮。省政府“暢通工程”的目標是使全省任何兩個城鎮間都可以實現交通(但不一定有直接的道路相連,只要互相間接通過道路可達即可)。問最少還需要建設多少條道路。

輸入: 測試輸入包含若干測試案例。每個測試案例的第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 提示: 
 Huge input, scanf is recommended. 

AC代碼

/*並查集入門HDU12322017年7月28日19:41:07 */ #include<stdio.h>#include<set>using namespace std;const int maxn=1010;int pre[maxn];int find(int x){int r=x;while(pre[r]!=r)r=pre[r];//尋找到根節點為止 int i=x,j;while(i!=r){j=pre[i];pre[i]=r;i=j;}return r; }void join(int x,int y){int fx=find(x);int fy=find(y);if(fx!=fy) pre[fx]=fy;}int main(){int n,m;while(scanf("%d%d",&n,&m)==2&&n){for(int i=1;i<=n;i++)pre[i]=i;for(int i=1;i<=m;i++){int a,b;scanf("%d%d",&a,&b);join(a,b);}/*第一種方法,求祖先的數量,把所有節點遍曆一遍如果發現某個點的 祖先 是他自己,那麼這個點一定是祖先節點統計數量,最後結果減一,因為N個連通分量,只需要N-1條路徑就可以將n個連通分量 合并成一個 */ int ans=0;for(int i=1;i<=n;i++){if(find(i)==i) ans++;}printf("%d\n",ans-1);/*這是第二種方法,把每個點的祖先,放到set 裡面,因為集合內建去重,所以裡面的元素個數,即為聯通分量的個數 set<int> ans;for(int i=1;i<=n;i++){int r=find(i);ans.insert(r);}printf("%d\n",ans.size()-1);*/} return 0;} 


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.