zoj 1586 最小生成树 prim算法

链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=586

题意:有n个适配器,不同的适配器价格不同,并给出两个适配器之间如果连接所需的网线价格,要用网线使它们连通,求所需最小费用。

思路:计算建立网络的最小费用,是个最小生成树问题。注意在构造有向网时,每条边的权值为网线的价格加上网线所连接的两个适配器的价格。由于只要求最小生成树的权值而不求选择的边,所以把lowcost数组和nearvex数组合并,lowcost[i]=-1仍表示i在集合T内。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<string>
#include<cmath>
#include<map>
using namespace std;

const int INF=1000000;
const int maxn=1000+5;
int n;
int edge[maxn][maxn];
int lowcost[maxn];
int adapter[maxn];
void init()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)
       scanf("%d",&adapter[i]);
    for(int i=0;i<n;i++)
       for(int j=0;j<n;j++)
       {
           scanf("%d",&edge[i][j]);
           if(i==j) edge[i][j]=INF;
           else edge[i][j]+=adapter[i]+adapter[j];
       }
}
void prim()
{
    int sumw=0;
    lowcost[0]=-1;
    for(int i=1;i<n;i++)
       lowcost[i]=edge[0][i];
    for(int i=1;i<n;i++)
    {
        int v,min=INF;
        for(int j=0;j<n;j++)
            if(lowcost[j]!=-1 && lowcost[j]<min)
            {
                v=j;
                min=lowcost[j];
            }
        sumw+=min;
        lowcost[v]=-1;
        for(int i=0;i<n;i++)
           if(lowcost[i]>edge[v][i])
              lowcost[i]=edge[v][i];
    }
    printf("%d\n",sumw);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        init();
        prim();
    }
    return 0;
}
原文地址:https://www.cnblogs.com/54zyq/p/3112602.html