poj1679The Unique MST(次小生成树模板)

次小生成树模板,别忘了判定不存在最小生成树的情况

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int maxn = 100 + 5;
const int inf = 0x3f3f3f3f;
int MAX[maxn][maxn], mp[maxn][maxn], dis[maxn], pre[maxn];
int t, n, m;
bool vis[maxn], used[maxn][maxn];
inline int min( int a,int b ){
    return a<b ? a:b;
}

inline int max( int a, int b ){
    return a>b ? a:b;
}

inline int prim(){
    int res = 0;
    memset( vis, 0, sizeof(vis) );
    memset( used, 0, sizeof(used) );
    memset( MAX, 0, sizeof(MAX) );
    for( int i=2; i<=n; i++ ){
        pre[i] = 1;
        dis[i] = mp[i][1];
    }
    vis[1] = 1;
    dis[1] = pre[1] = 0;
    for( int i=1; i<n; i++ ){
        int minid, MIN = inf;
        for( int j=1; j<=n; j++ ) if( !vis[j] && MIN>dis[j] ) MIN = dis[minid=j];
        if( MIN==inf ) return -1;        //不存在最小生成树
        res += MIN;
        vis[minid] = 1;
        used[minid][pre[minid]] = used[pre[minid]][minid] = 1;
        for( int j=1; j<=n; j++ ){
            if( vis[j] ) MAX[minid][j] = MAX[j][minid] = max( dis[minid], MAX[j][pre[minid]] );
            if( !vis[j] && dis[j]>mp[minid][j] ){
                pre[j] = minid;
                dis[j] = mp[minid][j];
            }
        }
    }
    return res;
}

int main(){
    scanf("%d", &t);
    while( t-- ){
        scanf("%d%d", &n, &m);
        memset( mp, inf, sizeof(mp) );
        for( int i=0; i<m; i++ ){
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            mp[u][v] = mp[v][u] = w;
        }
        int min_ans = prim(), ans = inf;
        if( min_ans==-1 ){ printf("Not Unique!\n"); continue; }    //不存在最小生成树
        for( int i=1; i<=n; i++ )
            for( int j=i+1; j<=n; j++ )
                if( mp[i][j]!=inf && !used[i][j] )
                    ans = min( ans, min_ans+mp[i][j]-MAX[i][j] );
        if( ans==min_ans ) printf("Not Unique!\n");
        else printf("%d\n", min_ans);
    }

    return 0;
}

 

posted @ 2019-05-16 01:20  CoffeeCati  阅读(111)  评论(0编辑  收藏  举报