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

Posted Yeader

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 1679 The Unique MST(次小生成树)相关的知识,希望对你有一定的参考价值。

题目链接: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(次小生成树)的主要内容,如果未能解决你的问题,请参考以下文章

POJ1679 The Unique MST[次小生成树]

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

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

POJ 1679 The Unique MST:次小生成树倍增

poj 1679 The Unique MST (次小生成树(sec_mst)kruskal)

The Unique MST POJ - 1679 次小生成树