标签:std nbsp print 瓶颈 注意 for ref prim scan
题目链接:http://poj.org/problem?id=1679
题目大意:求出最小生成树,并且判断最小生成树是否唯一,即次小生成树的路径和是否等于最小生成树,是则输出路径和,反之输出"Not unique!".
解题思路:求次小生成树,我看的是O(n^2)的算法,先计算各点间的最小瓶颈路Max[i][j](表示MST中i到j最大边权值,即最小瓶颈路),因为次小生成树肯定是通过替换掉一条最小生成树中的边得来的,所以通过枚举替换Max[i][j]为cost[i][j]得到次小生成树。
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int N=1e2+5; 7 const int INF=0x3f3f3f3f; 8 9 int n,m; 10 int cost[N][N],low[N],pre[N],Max[N][N];//数组Max[i][j]表示MST中i到j最大边权值,即最小瓶颈路 11 bool vis[N]; 12 13 //求最小生成树,及最小瓶颈路 14 int Prim(){ 15 memset(vis,false,sizeof(vis)); 16 for(int i=1;i<=n;i++){ 17 low[i]=cost[1][i]; 18 pre[i]=1; 19 } 20 int ans=0; 21 vis[1]=true; 22 pre[1]=-1; 23 //添加n-1条边 24 for(int i=1;i<n;i++){ 25 int k=-1; 26 for(int j=1;j<=n;j++){ 27 if(!vis[j]&&(k==-1||low[k]>low[j])){ 28 k=j; 29 } 30 } 31 if(k==-1||low[k]==INF) return -1; 32 ans+=low[k]; 33 cost[pre[k]][k]=cost[k][pre[k]]=INF; 34 //注意先计算完Max[k][j],再vis[k] =true; 35 for(int j=1;j<=n;j++){ 36 if(vis[j]) 37 Max[k][j]=Max[j][k]=max(Max[pre[k]][j],low[k]); 38 } 39 vis[k]=true; 40 for(int j=1;j<=n;j++){ 41 if(!vis[j]&&low[j]>cost[k][j]){ 42 low[j]=cost[k][j]; 43 pre[j]=k; 44 } 45 } 46 } 47 return ans; 48 } 49 //求次小生成树 50 int smst(int ans){ 51 int Min=INF; 52 for(int i=1;i<=n;i++){ 53 for(int j=i+1;j<=n;j++){ 54 if(cost[i][j]!=INF) 55 Min=min(Min,ans+cost[i][j]-Max[i][j]); 56 } 57 } 58 return Min; 59 } 60 61 int main(){ 62 int t; 63 scanf("%d",&t); 64 while(t--){ 65 memset(cost,0x3f,sizeof(cost)); 66 scanf("%d%d",&n,&m); 67 for(int i=1;i<=m;i++){ 68 int a,b,c; 69 scanf("%d%d%d",&a,&b,&c); 70 cost[a][b]=cost[b][a]=c; 71 } 72 int ans=Prim(); 73 if(ans==-1) 74 puts("Not Unique!"); 75 else if(ans==smst(ans)) 76 puts("Not Unique!"); 77 else 78 printf("%d\n",ans); 79 } 80 return 0; 81 }
POJ 1679 The Unique MST(次小生成树)
标签:std nbsp print 瓶颈 注意 for ref prim scan
原文地址:http://www.cnblogs.com/fu3638/p/7905253.html