因為從來沒有接觸過並查集,但是前幾天測試中出現了並查集的題,我也開始關注了起來,並且經過幾天的研究終於搞懂了.以下是當時的題
7-4 檔案傳輸 (25 分)
當兩臺計算機雙向連通的時候,檔案是可以在兩臺機器間傳輸的。給定一套計算機網路,請你判斷任意兩臺指定的計算機之間能否傳輸檔案?
輸入格式:
首先在第一行給出網路中計算機的總數 N (2≤N≤104),於是我們假設這些計算機從 1 到 N 編號。隨後每行輸入按以下格式給出:
I c1 c2
其中I
表示在計算機c1
和c2
之間加入連線,使它們連通;或者是
C c1 c2
其中C
表示查詢計算機c1
和c2
之間能否傳輸檔案;又或者是
S
這裡S
表示輸入終止。
輸出格式:
對每個C
開頭的查詢,如果c1
和c2
之間可以傳輸檔案,就在一行中輸出"yes",否則輸出"no"。當讀到終止符時,在一行中輸出"The network is connected."如果網路中所有計算機之間都能傳輸檔案;或者輸出"There are k
components.",其中k
是網路中連通集的個數。
輸入樣例 1:
5
C 3 2
I 3 2
C 1 5
I 4 5
I 2 4
C 3 5
S
輸出樣例 1:
no
no
yes
There are 2 components.
輸入樣例 2:
5
C 3 2
I 3 2
C 1 5
I 4 5
I 2 4
C 3 5
I 1 3
C 1 5
S
輸出樣例 2:
no
no
yes
yes
The network is connected.
單位: 浙江大學
時間限制: 150 ms
記憶體限制: 64 MB
程式碼長度限制: 16 KB
這道題乍一看我想到的是DFS,但是在向下繼續寫的過程中便暴露了很多問題,知道我搞懂了並查集,才發現這題是這麼簡單
以下是我的程式碼:
1 #include<stdio.h> 2 int pre[10000];//當時少了一個0得注意 3 int find(int x){ 4 if(pre[x]!=x){ 5 pre[x] = find(pre[x]); //如果自己的老大不是自己,那麼就遞迴繼續尋找老大 6 } 7 return pre[x]; //找到老大就返回 8 } 9 void join(int x,int y){ 10 int fx = find(x); 11 int fy = find(y); 12 if(fx!=fy){ 13 pre[fx] = fy; //將兩個不同的老大連通 14 } 15 } 16 int main() 17 { 18 int n; //一共多少臺電腦 19 char s; //狀態 20 int a,b; //電腦名稱 21 int i,j,k;//迴圈變數 22 scanf("%d",&n); 23 for(i=0;i<n;i++){ 24 pre[i] = i;//初始化電腦狀態,每個人都只是與自己連通 25 } 26 while(~scanf("%c",&s)){ 27 if(s=='S'){ 28 break;//輸入S程式結束 29 } 30 scanf("%d %d",&a,&b);//我習慣從0開始 31 if(s=='C'){ //查詢 32 if(find(a-1)==find(b-1)){ 33 printf("yes\n"); //說明兩個老大一樣,所以連通 34 }else{ 35 printf("no\n"); 36 } 37 } 38 if(s=='I'){//如果兩臺機子不連通就讓他們連通 39 join(a-1,b-1); 40 } 41 } 42 int cut=0; 43 for(i=0;i<n;i++){ 44 if(find(i)==i){ 45 cut++; 46 } 47 } 48 if(cut==1)printf("The network is connected.");//如果只有一個老大說明大家都連通 49 else printf("There are %d components.",cut); 50 }
通過這道題,我感覺我要學的東西還有很多,我會一點一點繼續學習更多的知識的.