1. 程式人生 > >HDU1863_暢通project【Prim】【並查集】

HDU1863_暢通project【Prim】【並查集】

計數 道路 不足 rim scanf article ava 能夠 else

暢通project

Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 17867 Accepted Submission(s): 7552
Problem Description
省政府“暢通project”的目標是使全省不論什麽兩個村莊間都能夠實現公路交通(但不一定有直接的公路相連,僅僅要能間接通過公路可達就可以)。

經過調查評估,得到的統計表中列出了有可能建設公路的若幹條道路的成本。現請你編敲代碼,計算出全省暢通須要的最低成本。



Input
測試輸入包括若幹測試用例。

每一個測試用例的第1行給出評估的道路條數 N、村莊數目M ( < 100 );隨後的 N
行相應村莊間道路的成本,每行給出一對正整數,各自是兩個村莊的編號,以及此兩村莊間道路的成本(也是正整數)。

為簡單起見,村莊從1到M編號。

當N為0時,所有輸入結束,相應的結果不要輸出。



Output
對每一個測試用例。在1行裏輸出全省暢通須要的最低成本。

若統計數據不足以保證暢通,則輸出“?”。

Sample Input
3 3
1 2 1
1 3 2
2 3 4
1 3
2 3 2
0 100

Sample Output
3
?

Source

浙大計算機研究生復試上機考試-2007年

題目大意:給你M個村莊、N條路,即N條路所連接的兩個村莊即路程。

問是否能各個村莊都能有路達到,若不通。則輸出‘?‘,若通,則計算出連接

全部村莊最小的路程和

思路:先用並查集推斷是否能全部村莊。

把有路連接的村莊並到一個集合裏。

最後,若僅僅有一個集合。則全部村莊都能連接。若有兩個以上,則肯定有

村莊不能到達。

然後用Prim算法計算出圖的最小生成樹。

#include<stdio.h>
#include<string.h>

int N,M;
int map[110][110],vis[110],low[110];
int father[110];

int find(int a)
{
    if(a != father[a])
        father[a] = find(father[a]);
    return father[a];
}
int prim()
{
    int pos,res = 0;
    memset(vis,0,sizeof(vis));
    vis[1] = 1;
    pos = 1;
    for(int i = 1; i <= M; i++)
        if(i != pos)
            low[i] = map[pos][i];

    for(int i = 1; i < M; i++)
    {
        int Min = 0xffffff0;
        for(int j = 1; j <= M; j++)
        {
            if(vis[j] == 0 && Min > low[j])
            {
                Min = low[j];
                pos = j;
            }
        }
        res += Min;
        vis[pos] = 1;

        for(int j = 1; j <= M; j++)
        {
            if(vis[j] == 0 && low[j] > map[pos][j])
                low[j] = map[pos][j];
        }
    }
    return res;
}
int main()
{

    int posi,posj,cost;
    while(~scanf("%d%d",&N,&M) && N!=0)
    {
        for(int i = 1; i <= M; i++)
            father[i] = i;
        for(int i = 1; i <= M; i++)
        {
            for(int j = 1; j <= M; j++)
            {
                map[i][j] = 0xffffff0;
            }
        }
        while(N--)
        {
            scanf("%d%d%d",&posi,&posj,&cost);
            map[posi][posj] = map[posj][posi] = cost;
            int a = find(posi);
            int b = find(posj);
            if(a != b)
            {
                father[b] = a;
            }
        }
        int a = find(1);
        int flag = 1;
        for(int i = 2; i <= M; i++)
        {
            if(find(i)!=a)
            {
                flag = 0;
            }
        }

        if(flag == 0)
            printf("?

\n"); else { int ans = prim(); printf("%d\n",ans); } } return 0; }



HDU1863_暢通project【Prim】【並查集】