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

      题目链接:http://poj.org/problem?id=1679

      求是否存在多个最小生成树,其实就是求次小生成树的权值是否等于最小生成树。

      最小生成树的两个性质:

        1.切割性质:假定所有边权值不相等,设S为即非空集合也非全集V的子集,边e是满足一个端点在S内,另一个端点不在S内的所有边中权值最小的一个,则图G的所有生成树均包含e。

        2.回路性质:假定所有边权值不相等,设C是图G中的任意回路,边e是C上权值最大的边,则图G的所有生成树均不包含e。

      求次小生成树一遍朴素的做法就是枚举最小生成树中的边删去,然后再在图上求最小生成树,复杂度O(n*m*lgm);对于稀疏图来说,复杂度还是不高的。还有一种更好的方法,就是利用性质2。在最小生成树上家一条边u-v之后,图上会出现一条回路,因此删除的必须在最小生成树上u-v的路径上,而且是这条路径上的最长边。可以证明,次小生成树一定可以由最小生成树加一条边再删一条边得到(边交换)。因此只需求出”每对节点之间的最小瓶颈路“之后,然后依次枚举m条边就可以了。总复杂度O(n^2);

     1 //STATUS:C++_AC_0MS_368KB
     2 #include<stdio.h>
     3 #include<stdlib.h>
     4 #include<string.h>
     5 #include<math.h>
     6 #include<iostream>
     7 #include<string>
     8 #include<algorithm>
     9 #include<vector>
    10 #include<queue>
    11 #include<stack>
    12 using namespace std;
    13 #define LL __int64
    14 #define pdi pair<double,int>
    15 #define Max(a,b) ((a)>(b)?(a):(b))
    16 #define Min(a,b) ((a)<(b)?(a):(b))
    17 #define mem(a,b) memset(a,b,sizeof(a))
    18 #define lson l,mid,rt<<1
    19 #define rson mid+1,r,rt<<1|1
    20 const int N=110,M=1000000,INF=0x3f3f3f3f,MOD=1999997;
    21 const LL LLNF=0x3f3f3f3f3f3f3f3fLL;
    22 const double DNF=100000000;
    23 
    24 struct Edge{
    25     int u,v,w;
    26 }e[N*N];
    27 int p[N],vis[N],mst[N][N],d[N][N],w[N][N];
    28 int T,n,m,mt;
    29 
    30 int cmp(const Edge& a,const Edge& b)
    31 {
    32     return a.w<b.w;
    33 }
    34 
    35 int find(int x){return p[x]==x?x:p[x]=find(p[x]);}
    36 
    37 int dfs(int& s,int u,int max)
    38 {
    39     int v;
    40     for(v=1;v<=n;v++){
    41         if(mst[u][v] && !vis[v]){
    42             vis[v]=1;
    43             d[s][v]=Max(max,w[u][v]);
    44             dfs(s,v,d[s][v]);
    45         }
    46     }
    47     return 0;
    48 }
    49 
    50 int Kruskal()
    51 {
    52     int i,j,x,y,sum=0;
    53     for(i=1;i<=n;i++)p[i]=i;
    54     sort(e,e+m,cmp);
    55     mem(mst,0);
    56     for(i=0;i<m;i++){
    57         x=find(e[i].u);
    58         y=find(e[i].v);
    59         if(x!=y){
    60             sum+=e[i].w;
    61             p[y]=x;
    62             mst[e[i].u][e[i].v]=mst[e[i].v][e[i].u]=1;
    63         }
    64     }
    65     return sum;
    66 }
    67 
    68 int main()
    69 {
    70   //  freopen("in.txt","r",stdin);
    71     int i,j,a,b,c,ok,ans;
    72     scanf("%d",&T);
    73     while(T--)
    74     {
    75         mt=0;
    76         mem(w,-1);
    77         scanf("%d%d",&n,&m);
    78         for(i=0;i<m;i++){
    79             scanf("%d%d%d",&a,&b,&c);
    80             w[a][b]=w[b][a]=c;
    81             e[i].u=a,e[i].v=b,e[i].w=c;
    82         }
    83 
    84         ans=Kruskal();
    85         for(i=1;i<=n;i++){
    86             mem(vis,0);vis[i]=1;
    87             dfs(i,i,0);
    88         }
    89         for(i=0,ok=1;i<m;i++)
    90             if(d[e[i].u][e[i].v]==e[i].w &&
    91                !mst[e[i].u][e[i].v]){ok=0;break;}
    92 
    93         if(ok)printf("%d\n",ans);
    94         else printf("Not Unique!\n");
    95     }
    96     return 0;
    97 }
  • 相关阅读:
    CORS实践
    xunsearch使用记录
    apk的php解析
    MYSQLI_USE_RESULT or MYSQLI_STORE_RESULT
    企业图谱
    《软件需求工程》阅读笔记03
    2020年下半年学习进度12
    《软件需求工程》阅读笔记02
    2020年下半年学习进度11
    《软件需求工程》阅读笔记01
  • 原文地址:https://www.cnblogs.com/zhsl/p/2886808.html
Copyright © 2011-2022 走看看