标签:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 27651 | Accepted: 9909 |
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!
求次小生成树步骤:
1)用prime求最小生成树,并记录树中u,v结点路径之间边的权值的最大值dp[u][v]。
2)一次枚举u,v结点不在最小生成树中的边,并将dp[u][v]删除,形成新的树。记录形成所有新树的权值的最小值。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAXN=105; const int INF=0x3f3f3f3f; int arc[MAXN][MAXN]; int n,m; int d[MAXN],vis[MAXN]; int pre[MAXN],dp[MAXN][MAXN]; bool mst[MAXN][MAXN]; int prim(int src) { memset(pre,0,sizeof(pre)); memset(mst,false,sizeof(mst)); memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) { vis[i]=0; d[i]=INF; } d[src]=0; int t=n; int res=0; while(t--) { int mincost=INF; int k; for(int i=1;i<=n;i++) { if(!vis[i]&&d[i]<mincost) { k=i; mincost=d[i]; } } vis[k]=1; res+=mincost; int fa=pre[k]; mst[fa][k]=true; mst[k][fa]=true; for(int i=1;i<=n;i++) { if(vis[i]&&i!=k) { dp[k][i]=dp[i][k]=max(dp[fa][i],mincost); } } for(int i=1;i<=n;i++) { if(!vis[i]&&d[i]>arc[k][i]) { d[i]=arc[k][i]; pre[i]=k; } } } return res; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i==j) arc[i][j]=0; else arc[i][j]=INF; for(int i=0;i<m;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); arc[u][v]=w; arc[v][u]=w; } int res=prim(1); int nmx=INF; for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { if(arc[i][j]!=INF&&!mst[i][j]) { nmx=min(nmx,res+arc[i][j]-dp[i][j]); } } } if(nmx==res) { printf("Not Unique!\n"); } else { printf("%d\n",res); } } return 0; }
标签:
原文地址:http://www.cnblogs.com/program-ccc/p/5816035.html