POJ 1679 次小生成樹
阿新 • • 發佈:2018-11-17
題目連結:http://poj.org/problem?id=1679
題目思路:次小生成樹的模板題,其中蘊含的小操作還是有點東西的
AC程式碼
#include <iostream> #include<cstdio> #include<cstring> using namespace std; #define inf 0x3f3f3f3f #define N 130 int dis[N][N]; int use[N][N]; int pre[N]; int low[N]; int ans; int via[N]; int n,m; int maxn[N][N]; int prim() { ans=0; memset(via,0,sizeof(via)); via[1]=1; for(int i=1;i<=n;++i) maxn[i][i]=0; for(int i=2;i<=n;++i) low[i]=dis[1][i]; for(int i=1;i<n;++i) { int minn=inf; int bj=-1; for(int j=1;j<=n;++j) { if(!via[j]&&minn>low[j]) { minn=low[j]; bj=j; } } if(bj==-1) return -1; ans+=minn; for(int j=1;j<=n;++j) { if(via[j]) maxn[j][bj]=maxn[bj][j]=max(maxn[j][pre[j]],minn); else { if(low[j]>dis[j][bj]) { low[j]=dis[j][bj]; pre[j]=bj; } } } via[bj]=1; use[bj][pre[bj]]=use[pre[bj]][bj]=1; } return ans; } int f() { int res=inf; for(int i=1;i<=n;++i) { for(int j=1;j<=n;++j) { if(use[i][j]==0&&dis[i][j]!=inf) res=min(res,ans-maxn[i][j]+dis[i][j]); } } return res; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); memset(low,inf,sizeof(low)); memset(dis,inf,sizeof(dis)); memset(use,0,sizeof(use)); for(int i=0;i<=n;++i) pre[i]=1; for(int i=1;i<=m;++i) { int x,y,z; scanf("%d%d%d",&x,&y,&z); dis[x][y]=dis[y][x]=z; } prim(); if(f()==ans) printf("Not Unique!\n"); else printf("%d\n",ans); } return 0; }