POJ 1679The Unique MST(次小生成树)

来源:互联网 发布:电气设备市场数据 编辑:程序博客网 时间:2024/05/20 10:23

题目链接:http://poj.org/problem?id=1679

题目大意:求是否有多条相等权值的最小生成树, 如果有输出  Not Unique!,否则输出最小生成树的值这是一道次小生成树的题, 就是看次小生成树的值和生成树的值是否相等

 *次小生成树  * 求最小生成树时,用数组Max[i][j]来表示MST中i到j最大

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int maxn = 100 + 10;const int INF = 0x3f3f3f3f;bool vis[maxn][maxn], used[maxn];int G[maxn][maxn], lowcost[maxn], closeset[maxn];int Max[maxn][maxn]; //存点i.j之间边的最大权值int Prime(int n){    int ans = 0;    for(int i = 1; i <= n; i++)    {        lowcost[i] = G[1][i];        closeset[i] = 1;    }    memset(Max, 0, sizeof(Max));    memset(vis, false, sizeof(vis));    memset(used, false, sizeof(used));    used[1] = true;    closeset[1] = -1;    for(int i = 1; i < n; i++)    {        int p = -1, minn = INF;        for(int j = 1; j <= n; j++)            if(!used[j] && minn>lowcost[j])        {            minn = lowcost[j];            p = j;        }        if(minn == INF)            return -1;        used[p] = true;        ans += minn;        vis[p][closeset[p]] = vis[closeset[p]][p] = true;        for(int j = 1; j <= n; j++)        {            if(used[j])                Max[j][p] = Max[p][j] = max(Max[j][closeset[p]], lowcost[p]);            if(!used[j] && lowcost[j]>G[p][j])            {                lowcost[j] = G[p][j];                closeset[j] = p;            }        }     }     return ans;}int main(){    int T, n, m, a, b, c;    scanf("%d", &T);    while(T--)    {        scanf("%d%d", &n, &m);        for(int i = 1; i <= n; i++)            for(int j = 1; j <= n; j++)                 G[i][j] = INF;        while(m--)        {            scanf("%d%d%d", &a, &b, &c);            G[a][b] = G[b][a] = c;        }        int ans = Prime(n);        int k = INF;        for(int i = 1; i <= n; i++)            for(int j = 1; j <= n; j++)                if(!vis[i][j])                    k = min(k, ans-Max[i][j]+G[i][j]);        if(k == ans)            printf("Not Unique!\n");        else            printf("%d\n", ans);    }    return 0;}

边权  * 求完后,直接枚举所有不在MST中的边,替换掉最大边权的边,更新答案 

0 0