HDU 1863(最小生成树)

来源:互联网 发布:装饰定额预算软件 编辑:程序博客网 时间:2024/06/04 20:01

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1863

这还是最小生成树的模版题, 以前都是用的Kruskal做的, 这次用Prime做的, 写篇博客记录下。Prime的复杂度为n^2(n为点的个数),与边的个数无关,用于稠密图, 而Kruskal的复杂度为mlgm(m为边的个数)与点的个数无关, 主要用于稀疏图。

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int INF = 1000000000;const int maxn = 100 + 10;int G[maxn][maxn], lowcost[maxn], closeset[maxn];//G数组存图, lowcost数组存的是能到达顶点i的最小权值, closeset数组为到达i顶点的前一个顶点,可用来输出路径bool used[maxn];//用来标记顶点是否选过int Prime(int n){    int ans = 0;    //假设是从第一个点开始    for(int i = 0; i < n; i++)    {        lowcost[i] = G[0][i];        closeset[i] = 0;        used[i] = false;    }    used[0] = true;    closeset[0] = -1;//用来路径输出时判断结束    for(int i = 1; i < n; i++)    {        int minn = INF, p = -1;        //查找到达各个顶点的最小权值        for(int j = 0; j < n; j++)            if(!used[j] && minn>lowcost[j])            {                minn = lowcost[j];                p = j;            }        //如果minn值为INF说明图不连通        if(minn == INF)            return -1;        used[p] = true;        ans += minn;        for(int j = 0; j < n; j++)            if(!used[j] && lowcost[j] > G[p][j])            {                lowcost[j] = G[p][j];                closeset[j] = p;            }    }    return ans;}int main(){    int n, m, a, b, c;    while(scanf("%d%d", &m, &n), m)    {        for(int  i = 0; i <= n; i++)            for(int j = 0; j <= n; j++)                G[i][j] = INF;        while(m--)        {            scanf("%d%d%d", &a, &b, &c);            G[a-1][b-1] = G[b-1][a-1] = c;        }        int ans = Prime(n);        if(ans != -1)            printf("%d\n", ans);        else            printf("?\n");    }    return 0;}


0 0