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