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);
    }  

}

 

你可能感兴趣的:(unique)