1. 程式人生 > 實用技巧 >並查集的實戰使用(綿羊趣題)

並查集的實戰使用(綿羊趣題)

上一篇文章,我抄了講了並查集的基本使用,這一次,我搞定了南外的一道綿羊趣題,當中用到了並查集。

話不多說,上題目和程式碼!


並查集趣題

抓羊

(存檔檔名為csheep.pas/c/cpp)

時間限制:1 sec 記憶體限制:128 MB

題目描述

老江帶著hh和南瓜搞不好到內蒙古旅遊,在野外老江想晚上吃燒全羊,於是他命令hh和南瓜搞不好去抓羊。他們倆來到一個地方見到茫茫多的野羊,他們給野羊標號為1..N。他們決定用若干條繩子將野羊相互連線起來帶給老江。當然,任意兩頭野羊之間只有一根繩子直接連線。輸入顯示野羊c1 和野羊 c2是已經連著的。

hh與南瓜搞不好將野羊們相互連在一起而且其中要有1號野羊(野羊首領,不然羊們帶不走)。但南瓜搞不好用繩子綁羊時“見羊就綁”,不論是不是與1號野羊在一起!綁完後,hh急了,想找出不符合要求的野羊,於是用程式找出(升序)沒有直接或間接連到1號羊的野羊編號(當然,1號野羊顯然與自己相連)。假如所有野羊都符合要求,則輸出0。

下面的例子中,有6頭野羊,4根繩子:

1---2 4---5

\ |

\ | 6

\|

3

顯然,4號野羊、5號野羊、6號野羊沒有直接或間接與1號羊相連。

請你也用程式找出不符合要求的野羊。

輸入格式

第1行:兩個用空格隔開的整數: N 與M (1≤N≤300,000,1≤ M≤600,000)其中N代表野羊的只數,M代表綁羊的繩子數。

第2..M+1行:第i+1行有兩個用空格隔開的整數c1和c2,表示野羊c1和野羊c2有繩直接相連 (1≤c1 ≤N; 1≤c2≤ N; c1≠c2)

輸出格式

輸出不符合要求的野羊的序號(升序)。

樣例

csheep.in

6 4

1 3

2 3

1 2

4 5

csheep.out

4

5

6

資料規模

對於全部的資料,有50%測試資料N≤10,000;

對於全部的資料,有100%測試資料N≤300,000.


原創程式碼

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int i,k,n,m,f[300000],p1,p2;
 4 int find(int k)//定義find函式 
 5 {
 6     if(f[k]==k)return k; 
 7     return f[k]=find(f[k]);
 8 }
 9 int
main() 10 { 11 freopen("csheep.in","r",stdin);//輸入檔案操作,不需要可以註釋掉 12 freopen("csheep.out","w",stdout);//輸出檔案操作 ,不需要可以註釋掉 13 cin>>n>>m; //輸入綿羊的數量,繩子的數量 14 for(i=1;i<=n;i++) 15 { 16 f[i]=i;//初始化,每隻羊都自己綁著自己 17 } 18 for(i=1;i<=m;i++) 19 { 20 cin>>p1>>p2;//重複輸入,互相綁住的羊A和羊B 21 f[find(p1)]=find(p2);//記錄:羊A綁住了羊B 22 } 23 for(i=1;i<=n;i++) 24 { 25 if(find(1)!=find(i))//反覆判斷,如果該羊最終沒有和羊1綁住 26 { 27 cout<<i<<endl;//就輸出它的編號 28 } 29 } 30 return 0; 31 }

這就是並查集趣題之抓羊,喜歡請支援。