Description
Input
Output
Sample Input
2 3 3 1 2 1 2 3 2 3 1 3 4 4 1 2 2 2 3 2 3 4 2 4 1 2
Sample Output
3 Not Unique!
模板题目,没啥可说的。
/**************************** * author:crazy_石头 * date:2014/01/18 * algorithm:次小生成树 * Pro:POJ 1679 * 次小生成树 * 求最小生成树时,用数组Max[i][j]来表示MST中i到j最大边权 * 求完后,直接枚举所有不在MST中的边,替换掉最大边权的边,更新答案 * 点的编号从0开始 ***************************/ #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <algorithm> #include <string> #include <queue> #include <vector> using namespace std; #define INF 1<<29 #define eps 1e-8 #define A system("pause") #define rep(i,h,n) for(int i=(h);i<=(n);i++) #define ms(a,b) memset((a),(b),sizeof(a)) const int maxn=100+10; const int maxm=3000+10; bool vis[maxn],used[maxn][maxn]; int lowc[maxn],pre[maxn],Max[maxn][maxn],ans,cost[maxn][maxn]; int test,n,m; inline int Prim(int cost[][maxn],int n) { int ans=0; ms(vis,0),ms(Max,0),ms(used,0); vis[0]=true,pre[0]=-1; for(int i=1;i<n;i++) { lowc[i]=cost[0][i]; pre[i]=0; } lowc[0]=0; for(int i=1;i<n;i++) { int minc=INF; int p=-1; for(int j=0;j<n;j++) if(!vis[j]&&minc>lowc[j]) { minc=lowc[j]; p=j; } if(minc==INF) return -1; ans+=minc; vis[p]=true; used[p][pre[p]]=used[pre[p]][p]=true; for(int j=0;j<n;j++) { if(vis[j]) Max[j][p]=Max[p][j]=max(Max[j][pre[p]],lowc[p]); if(!vis[j]&&lowc[j]>cost[p][j]) { lowc[j]=cost[p][j]; pre[j]=p; } } } return ans; } inline int smst(int cost[][maxn],int n) { int Min=INF; for(int i=0;i<n;i++) for(int j=i+1;j<n;j++) if(cost[i][j]!=INF&&!used[i][j]) Min=min(Min,ans+cost[i][j]-Max[i][j]); if(Min==INF) return -1; return Min; } int main() { scanf("%d",&test); while(test--) { int u,v,w; scanf("%d%d",&n,&m); rep(i,0,n-1) rep(j,0,n-1) i==j?cost[i][j]=0:cost[i][j]=INF; while(m--)//0开始 { scanf("%d%d%d",&u,&v,&w); u--,v--; cost[u][v]=cost[v][u]=w; } ans=Prim(cost,n); if(ans==-1) { printf("Not Unique!\n"); continue; } if(ans==smst(cost,n)) printf("Not Unique!\n"); else printf("%d\n",ans); } return 0; }