Hdu 1863 - 通畅工程

最小生成树 - prim算法

 

题意:n为路的数目,m为村庄数;若无法连通,则输出-1,否则输出最小权值;当n为0时,直接结束不用输出结果。

 

 

AC代码:

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

const int max = 0x7ffffff;
int map[105][105], v[105], low[105];
int n,m;

int MinTree(int n)
{
    int min,flag,i,j,sum;
    memset(v, 0, sizeof(v));
    memset(low, 0, sizeof(low));
    v[1] = 1;  //从村庄1开始贪心
    sum = 0;
    for(i=2; i<=m; i++) //此处的范围应是m村庄数,i为2~m中的一个村庄
    {
        low[i] = map[1][i];
    }
    for(i=2; i<=m; i++)
    //此处的范围应是m村庄数;如果是n边数的话,当最小生成树已经构建完的话,而边数小于村庄数,
    //则for会一直执行,而if则不成立,结果就是return -1.
    {
        min = max;
        flag = -1;
        for(j=1; j<=m; j++)
        {
            if(!v[j] && low[j]<min)
            {
                min = low[j];
                flag = j;
            }
        }
        if(min == max) return -1;
        sum += low[flag];
        v[flag] = 1;
        for(j=1; j<=m; j++)
        {
            if(!v[j] && low[j]>map[flag][j])
            {
                low[j] = map[flag][j];
            }
        }
    }
    return sum;
}

int main()
{
    int i,j,a,b,c,ans;
    while(scanf("%d%d",&n,&m),n)
    {
        for(i=1; i<=m; i++)  //初始化
            for(j=1; j<=m; j++)
            {
                if(i==j) map[i][j] = 0;
                else map[i][j] = max;
            }
        for(i=1; i<=n; i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            if(c < map[a][b])
            {
                map[a][b] = c;
                map[b][a] = c;
            }
        }
        ans = MinTree(n);
        if(ans<=0) printf("?\n");
        else printf("%d\n", ans);
    }
    return 0;
}

 

 


 

你可能感兴趣的:(Hdu 1863 - 通畅工程)