码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 1679 The Unique MST(次小生成树)

时间:2017-11-27 17:53:17      阅读:134      评论:0      收藏:0      [点我收藏+]

标签: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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!