K - The Unique MST - poj 1679

题目的意思已经说明了一切,次小生成树。。。
************************************************************************************
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;

const int maxn = 105;
const int oo = 0x7fffffff;

int G[maxn][maxn], path[maxn][maxn];//path记录两点之间的最大边值
bool use[maxn][maxn];//记录是否是最小生成树上面的边

int Prim(int N)
{
    int dist[maxn], vis[maxn]={0,1}, pre[maxn];
    int i, ans = 0, T = N-1;

    for(i=1; i<=N; i++)
    {
        pre[i] = 1;
        dist[i] = G[1][i];
    }
    while(T--)
    {
        int k = 1, mini = oo;

        for(i=1; i<=N; i++)
        {
            if(!vis[i] && mini > dist[i])
                mini = dist[i], k = i;
        }
        use[ pre[k] ][k] = use[k][ pre[k] ] = true;
        ans += mini; vis[k] = true;

        for(i=1; i<=N; i++)
        {
            if(vis[i] && k != i)
                path[k][i]=path[i][k] = max(path[pre[i]][i], mini);
            if(!vis[i] && dist[i] > G[k][i])
                dist[i] = G[k][i], pre[i] = k;
        }
    }

    return ans;
}
int OK(int N)//判断是否有次小生成树
{
    for(int i=1; i<=N; i++)
    for(int j=i+1; j<=N; j++)
    {
        //如果有边的长度与最小树上的边相等,就说明不唯一了
        if(!use[i][j] && path[i][j]==G[i][j])
            return 0;
    }

    return 1;
}

int main()
{
    int T;

    scanf("%d", &T);

    while(T--)
    {
        int i, j, N, M, u, v, w;

        scanf("%d%d", &N, &M);

        for(i=1; i<=N; i++)
        for(j=1; j<=N; j++)
        {
            G[i][j] = (i == j ? 0 : oo);
            path[i][j] = 0;
            use[i][j] = false;
        }

        while(M--)
        {
            scanf("%d%d%d", &u, &v, &w);
            G[u][v] = G[v][u] = w;
        }

        int ans = Prim(N);

        if(OK(N) == 0)
            printf("Not Unique!\n");
        else
            printf("%d\n", ans);
    } 

}

 

posted @ 2015-07-25 15:44  无忧望月  阅读(163)  评论(0编辑  收藏  举报
levels of contents