hdu 1233 还是畅通工程 (Prim算法)

模板

Prim算法:=(VE)是无向连通带权图,在生成树的过程中,把已经在生成树中的结点看作一个集合(U),把剩下的结点看作另一个集合(V-U),从连接两个集合的边中选择一条权值最小的边即可,直到U = V。

时间复杂度为:O(n*n)

空间复杂度:O(n)

适用于稠密图

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

const int INF = 0x3f3f3f3f;
const int MAXN = 105;
bool vis[MAXN];
int c[MAXN][MAXN];
int lowc[MAXN];    //记录初始点到各点的最小权值
int n;

int Prim()
{
    int ans = 0;
    memset(vis,false,sizeof(vis));
    vis[1] = true;                    //将1加入U集合中
    for(int i = 1; i <= n; i++)       //初始化,c[1][i]为初始点1到i的最小权值,若没有,则初始化为INF
        lowc[i] = c[1][i];
    for(int i = 2; i <= n; i++)
    {
        int minc = INF;
        int p = -1;
        for(int j = 1; j <= n; j++)        //在集合V-U中寻找距离集合U最进的顶点p
            if(!vis[j] && minc > lowc[j])
            {
                minc = lowc[j];
                p = j;
            }
        if(minc == INF) return -1;          //图不连通
        ans += minc;                        //最小权值累加
        vis[p] = true;
        for(int j = 1; j <= n; j++)        //找到p点后更新lowc[i]的值
            if(!vis[j] && lowc[j] > c[p][j])
                lowc[j] = c[p][j];
    }
    return ans;
}

int main()
{
    while(~scanf("%d",&n) && n)
    {
        int a,b,d;
        memset(c,INF,sizeof(c));
        for(int i = 1; i <= n*(n-1)/2; i++)
        {
            scanf("%d%d%d",&a,&b,&d);
            c[a][b] = d;
            c[b][a] = d;
        }
        printf("%d\n",Prim());
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/feynmanz/article/details/80764121
今日推荐