2017藍橋杯模擬 風險度量(並查集)

標題:風險度量
X星系的的防衛體系包含 n 個空間站。這 n 個空間站間有 m 條通信鏈路,構成通信網。
兩個空間站間可能直接通信,也可能通過其它空間站中轉。
對於兩個站點x和y (x != y), 如果能找到一個站點z,使得:
當z被破壞後,x和y無法通信,則稱z爲關於x,y的關鍵站點。
顯然,對於給定的兩個站點,關於它們的關鍵點的個數越多,通信風險越大。
你的任務是:已知網絡結構,求兩站點之間的通信風險度,即:它們之間的關鍵點的個數。
輸入數據第一行包含2個整數n(2 <= n <= 1000), m(0 <= m <= 2000),分別代表站點數,鏈路數。
空間站的編號從1到n。通信鏈路用其兩端的站點編號表示。
接下來m行,每行兩個整數 u,v (1 <= u, v <= n; u != v)代表一條鏈路。
最後1行,兩個數u,v,代表被詢問通信風險度的兩個站點。
輸出:一個整數,如果詢問的兩點不連通則輸出-1.
例如:
用戶輸入:
7 6
1 3 2 3
3 4 3 5
4 5 5 6
1 6
則程序應該輸出:
2
資源約定:
峯值內存消耗(含虛擬機) < 256M
CPU消耗  < 2000ms
請嚴格按要求輸出,不要畫蛇添足地打印類似:“請您輸入...” 的多餘內容。
所有代碼放在同一個源文件中,調試通過後,拷貝提交該源碼。
提交程序時,注意選擇所期望的語言類型和編譯器類型。

分析:

並查集,是一種管理元素分組情況的數據結構

(1)查詢元素所在組別,兩個元素是否屬於同一組

(2) 如果不在同一組,說明不連通,合併到同一組

#include<stdio.h>
int fd[1005],sum=0,s[2005][2];
int find(int x)//並查集,查詢是否在同一組
{
    if(fd[x]==x)
        return x;
    return fd[x]=find(fd[x]);
}
int main()
{
    int m,n,i,j,k1,k2,k;
    scanf("%d%d",&n,&m);
    for(i=0; i<m; i++)
        scanf("%d%d",&s[i][0],&s[i][1]);
    scanf("%d%d",&k1,&k2);
    for(i=0; i<m; i++)//遍歷被破壞的點,如果仍能連通,就不是關鍵點
    {
        for(j=0; j<n; j++)//初始化根節點都是自己
            fd[j]=j;
        for(k=0; k<m; k++)
            if(k!=i)
            {
                int a=find(s[k][0]);//查找根節點
                int b=find(s[k][1]);
                if(a!=b)//如果根節點不同,就將兩點連通
                    fd[a]=b;//合併所在組
            }
        int a=find(k1);//並查集判斷是否連通
        int b=find(k2);
        if(a!=b)//如果不連通,說明是關鍵點
            sum++;
    }
    printf("%d\n",sum);
    return 0;
}


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