zoukankan      html  css  js  c++  java
  • POJ1679 The Unique MST(次小生成树)

    可以依次枚举MST上的各条边并删去再求最小生成树,如果结果和第一次求的一样,那就是最小生成树不唯一。

    用prim算法,时间复杂度O(n^3)。

     1 #include<cstdio>
     2 #include<cstring>
     3 using namespace std;
     4 #define MAXN 111
     5 #define INF (1<<30)
     6 struct Edge{
     7     int u,v;
     8 }edge[MAXN];
     9 int NE;
    10 
    11 int n,G[MAXN][MAXN];
    12 int lowcost[MAXN],nearvex[MAXN];
    13 int prim(bool statue){
    14     for(int i=2;i<=n;++i) lowcost[i]=INF;
    15     lowcost[1]=0;
    16     int res=0;
    17     for(int i=0; i<n; ++i){
    18         int u=-1,min=INF;
    19         for(int v=1; v<=n; ++v){
    20             if(lowcost[v]!=-1 && lowcost[v]<min){
    21                 min=lowcost[v];
    22                 u=v;
    23             }
    24         }
    25         if(u==-1) return -1;
    26         if(statue && u!=1){
    27             edge[NE].u=nearvex[u]; edge[NE].v=u;
    28             ++NE;
    29         }
    30         lowcost[u]=-1;
    31         res+=min;
    32         for(int v=1; v<=n; ++v){
    33             if(lowcost[v]!=-1 && lowcost[v]>G[u][v]){
    34                 lowcost[v]=G[u][v];
    35                 nearvex[v]=u;
    36             }
    37         }
    38     }
    39     return res;
    40 }
    41 
    42 bool isUnique(int res){
    43     for(int i=0; i<NE; ++i){
    44         int tmp=G[edge[i].u][edge[i].v];
    45         G[edge[i].u][edge[i].v]=G[edge[i].v][edge[i].u]=INF;
    46         if(prim(0)==res) return 0; 
    47         G[edge[i].u][edge[i].v]=G[edge[i].v][edge[i].u]=tmp;
    48     }
    49     return 1;
    50 }
    51 
    52 int main(){
    53     int t,m,a,b,c;
    54     scanf("%d",&t);
    55     while(t--){
    56         scanf("%d%d",&n,&m);
    57         for(int i=1; i<=n; ++i){
    58             for(int j=1; j<=n; ++j) G[i][j]=INF;
    59         }
    60         for(int i=0; i<m; ++i){
    61             scanf("%d%d%d",&a,&b,&c);
    62             G[a][b]=G[b][a]=c;
    63         }
    64         NE=0;
    65         int res=prim(1);
    66         if(isUnique(res)) printf("%d
    ",res);
    67         else puts("Not Unique!");
    68     }
    69     return 0;
    70 } 

    有O(n^2)的算法,详见http://www.cnblogs.com/hxsyl/p/3290832.html

    算法,需要求出MST上任意两点路径上的最长边,删除这条边会形成两个连通分支而那两点就分别在这两个连通分支里;

    然后依次枚举所有不在MST上的边,删除边上两点路径上的最长边并加入MST,这样就构成另外一颗生成树了,并且是存在该边的前提下的最小生成树。

    计算MST任意两点路径上的最长边,可以在prim算法的过程中求出:每当一个点加入T集合前,计算出所有T集合的点到该点的最长边。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 #define MAXN 111
     6 #define INF (1<<30)
     7 
     8 int n,G[MAXN][MAXN];
     9 bool vis[MAXN][MAXN];
    10 int lowcost[MAXN],nearvex[MAXN],maxedge[MAXN][MAXN];
    11 int T[MAXN],NT;
    12 int prim(){
    13     memset(vis,0,sizeof(vis));
    14     memset(maxedge,0,sizeof(maxedge));
    15     NT=0;
    16     nearvex[1]=1;
    17     for(int i=2; i<=n; ++i) lowcost[i]=INF;
    18     lowcost[1]=0;
    19 
    20     int res=0;
    21     for(int i=0; i<n; ++i){
    22         int u=-1,mincost=INF;
    23         for(int v=1; v<=n; ++v){
    24             if(lowcost[v]!=-1 && lowcost[v]<mincost){
    25                 mincost=lowcost[v];
    26                 u=v;
    27             }
    28         }
    29 
    30         vis[nearvex[u]][u]=vis[u][nearvex[u]]=1;
    31         for(int i=0; i<NT; ++i) maxedge[T[i]][u]=maxedge[u][T[i]]=max(maxedge[T[i]][nearvex[u]],mincost);
    32         T[NT++]=u;
    33 
    34         res+=mincost;
    35         lowcost[u]=-1;
    36         for(int v=1; v<=n; ++v){
    37             if(lowcost[v]!=-1 && lowcost[v]>G[u][v]){
    38                 lowcost[v]=G[u][v];
    39                 nearvex[v]=u;
    40             }
    41         }
    42     }
    43     return res;
    44 }
    45 
    46 int SMST(){
    47     int res=INF;
    48     for(int i=1; i<=n; ++i){
    49         for(int j=i+1; j<=n; ++j){
    50             if(vis[i][j] || G[i][j]==INF) continue;
    51             res=min(res,G[i][j]-maxedge[i][j]);
    52         }
    53     }
    54     return res;
    55 }
    56 
    57 int main(){
    58     int t,m,a,b,c;
    59     scanf("%d",&t);
    60     while(t--){
    61         scanf("%d%d",&n,&m);
    62         for(int i=1; i<=n; ++i){
    63             for(int j=1; j<=n; ++j) G[i][j]=INF;
    64         }
    65         while(m--){
    66             scanf("%d%d%d",&a,&b,&c);
    67             G[a][b]=G[b][a]=c;
    68         }
    69         int res=prim();
    70         if(SMST()==0) puts("Not Unique!");
    71         else printf("%d
    ",res);
    72     }
    73     return 0;
    74 }
  • 相关阅读:
    华为OJ机试训练(一)
    mount CIFS return ERR -12 and report Cannot allocate memory
    ftk学习记(icon篇)
    使用jquery-mockjax模拟ajax请求做前台測试
    Objective-C 内存管理之 _ARC
    [LeetCode]Decode Ways
    设计模式六大原则——迪米特法则(LoD)
    ACM/ICPC2014鞍山现场赛E hdu5074Hatsune Miku
    2015届校园招聘笔试/面试 基础知识点 总结
    依据Path取Json指定节点的值
  • 原文地址:https://www.cnblogs.com/WABoss/p/5005601.html
Copyright © 2011-2022 走看看