數據結構大作業——並查集:檢查網絡

11並查集:檢查網絡

問題描述】

給定一個計算機網絡以及機器間的雙向連線列表,每一條連線允許兩端的計算機進行直接的文件傳輸,其他計算機間若存在一條連通路徑,也可以進行間接的文件傳輸。請寫出程序判斷:任意指定兩臺計算機,它們之間是否可以進行文件傳輸?

【輸入要求】

輸入若干測試數據組成。對於每一組測試,第1行包含一個整數N(≤10000),即網絡中計算機的總檯數,因而每臺計算機可用1到N之間的一個正整數表示。接下來的幾行輸入格式爲I C1 C2或者 C或者C C1C2或者S,其中C1和C2是兩臺計算機的序號,I表示在C1和C2間輸入一條連線,C表示檢查C1和C2間是否可以傳輸文件,S表示該組測試結束。當N爲0時,表示全部測試結束,不要對該數據做任何處理。

輸出要求

對每一組C開頭的測試,檢查C1和C2間是否可以傳輸文件,若可以,則在一行中輸出“yes”,否則輸出“no”。當讀到S時,檢查整個網絡。若網絡中任意兩機器間都可以傳輸文件,則在一行中輸出“The network is connected.”,否則輸出“There are kcomponents.”,其中k是網絡中連通集的個數。兩組測試數據之間請輸出一空行分隔。


最簡單的數據結構作業了,就是一道acm題,也不用什麼亂七八糟的話,僅僅百行以內的代碼就搞定。

跟題目一個樣子就是一道並查集的問題:

把兩種典型的並查集問題聯繫到了一起:1、查詢兩個是否是連通的。2、看總共有幾個連通區,跟暢通工程是一樣的問題。

再注意一些細節的輸入輸出的處理即可:

自己還編了一組測試數據,進行測試:

還有用了路徑壓縮的優化方法微笑

#include <iostream>
#include <stdio.h>
using namespace std;
#define maxn 10002///N(≤10000)
int set[maxn];///設置操作數組
int rank[maxn];///按秩壓縮的秩數
void init(int n)
{
    for(int i=1;i<=n;i++)
    {
        set[i]=i;///初始化,把父節點都設爲自己本身
        rank[i]=1;///設秩的初值
    }
}
int find(int x)///帶路徑壓縮的向上查找
{
    if(set[x]==x)
        return  x;
    return set[x]=find(set[x]);
}
void union_set(int a,int b)///合併,當執行I操作即把兩臺電腦連接在一起的時候,將父節點設在一起即可
{
    int ta=find(a);
    int tb=find(b);
    if(ta==tb)
        return ;
    if(ta!=tb)
        set[ta]=set[tb];
}
int main()
{
    int n;
    char c;
    int a,b;
    while(~scanf("%d",&n),n){///當讀到0的時候,所有操作結束
        init(n);///對一組操作數,先初始化
        while(1)
        {
            scanf("%c",&c);///輸入操作符
            if(c=='C'){///C操作表示查詢兩臺電腦是否相連
                scanf(" C%d C%d",&a,&b);///讀數據的操作處理不是特別好
                if(find(a)==find(b))///相連“yes”
                    printf("yes\n");
                else
                    printf("no\n");
            }
            if(c=='I')///I操作表示將兩臺電腦,連接在一起
            {
                scanf(" C%d C%d",&a,&b);
                union_set(a,b);///使用union連接操作
            }
            if(c=='S')///S操作,查詢整個網絡連通情況。並且表示該組數據全部結束
            {
                int tmp=0;///用來標記有幾個連通區
                for(int i=1;i<=n;i++)
                {
                    if(set[i]==i)
                        tmp++;
                }
                if(tmp==1)///只有一個連通區的時候,表示全部連接
                    printf("The network is connected.\n");
                else///否則要輸出有多少個並且輸出個數
                    printf("There are %d components.\n",tmp);
                break;
            }
        }
    }
    return 0;
}
/**測試數據
輸入:
5
I C1 C2
I C2 C3
C C1 C3
C C2 C4
S
10
I C3 C4
I C4 C5
I C6 C7
I C8 C9
I C7 C9
C C6 C8
C C3 C5
C C1 C10
S
3
I C1 C2
I C2 C3
S
0
輸出
yes
no
There are 3 components.
yes
yes
no
There are 5 components.
The network is connected.
**/



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章