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 }
  • 相关阅读:
    maven之私服搭建
    maven之自定义archetype
    maven之自定义插件
    任务调度之 Elastic Job
    雪花算法原理解析
    基于 zxing 的二维码生成、解析
    spring-cloud-oauth2 认证授权
    spring security 自定义短信验证登录
    spring security session管理
    JDK1.8之HashMap实现原理
  • 原文地址:https://www.cnblogs.com/WABoss/p/5005601.html
Copyright © 2011-2022 走看看