• 次小生成树(poj 1679)


    次小生成树讲的比较详细的:

    http://www.cppblog.com/MatoNo1/archive/2011/05/29/147627.aspx

    对于prim算法的三种特殊

    另外注意三种特殊情况:【1】图G不连通,此时最小生成树和次小生成树均不存在。判定方法:在扩展T的过程中找不到新的可以加入的边;【2】图G本身就是一棵树,此时最小生成树存在(就是G本身)但次小生成树不存在。判定方法:在成功求出T后,发现邻接矩阵中的值全部是无穷大;【3】图G存在平行边。这种情况最麻烦,因为这时代价最小的可行变换(-E1, +E2)中,E1和E2可能是平行边!因此,只有建立两个邻接矩阵,分别存储每两点间权值最小的边和权值次小的边的权值,然后,每当一条新边(i, j)加入时,不是将邻接矩阵中边(i, j)权值改为无穷大,而是改为连接点i、j的权值次小的边的权值。

    第三点的平行边指的是什么不是很理解。难道是指重边??如果有人知道的话希望告知一下。先谢谢了。。太弱。

    附上poj 1679的代码:(没有注意第三点的特殊情况)

    View Code
      1 // File Name: 1679.cpp
      2 // Author: Missa
      3 // Created Time: 2013/2/22 星期五 22:46:03
      4 
      5 #include<iostream>
      6 #include<cstdio>
      7 #include<cstring>
      8 #include<algorithm>
      9 #include<cmath>
     10 #include<queue>
     11 #include<stack>
     12 #include<string>
     13 #include<vector>
     14 #include<cstdlib>
     15 #include<map>
     16 #include<set>
     17 using namespace std;
     18 #define CL(x,v) memset(x,v,sizeof(x));
     19 #define R(x,st,en) for(int x=st;x<en;x++)
     20 
     21 const int maxn = 105;
     22 const int inf = 0x3f3f3f3f;
     23 int g[maxn][maxn],dis[maxn];
     24 int path[maxn][maxn];//i,j路径上的最大的边权
     25 int n,m;
     26 int pre[maxn];
     27 bool vis[maxn];
     28 int prim()
     29 {
     30     R(i,1,n+1)
     31     {
     32         pre[i]=0;
     33         vis[i]=0;
     34         dis[i]=g[1][i];
     35         g[1][i]=g[i][1]=inf;
     36     }
     37     vis[1]=1;
     38     int ans=0;
     39     R(i,1,n)
     40     {
     41         int MIN = inf,flag=-1;
     42         R(j,1,n+1)
     43         {
     44             if(!vis[j] && dis[j]<MIN)
     45             {
     46                 flag=j;
     47                 MIN=dis[j];
     48             }
     49         }
     50         if(flag==-1) return -1;//不是连通的
     51         int p=pre[flag];
     52         path[p][flag]=path[flag][p]=MIN;
     53         R(j,1,n+1)
     54         {
     55             if(vis[j]&& j!=p)
     56                 path[flag][j]=path[j][flag]=max(path[p][j],MIN);
     57         }
     58         vis[flag]=1;
     59         ans+=MIN;
     60         R(j,1,n+1)
     61         {
     62             if(!vis[j] && dis[j]>g[flag][j])
     63             {
     64                 dis[j]=g[flag][j];
     65                 pre[j]=flag;
     66             }
     67         }
     68         g[flag][p]=g[p][flag]=inf;//将该边从原图中消除
     69     }
     70     return ans;
     71 }
     72 int main()
     73 {
     74     int t;
     75     scanf("%d",&t);
     76     while(t--)
     77     {
     78         int u,v,w;
     79         scanf("%d%d",&n,&m);
     80         R(i,1,n+1)
     81             R(j,1,n+1)
     82                 g[i][j]=g[j][i]=inf;
     83         R(i,1,n+1)
     84             g[i][i]=0;
     85         R(i,0,m)
     86         {
     87             scanf("%d%d%d",&u,&v,&w);
     88             g[u][v]=g[v][u]=w;
     89         }
     90         int ans=prim();
     91         if(ans==-1)
     92         {
     93             puts("0");
     94             continue;
     95         }
     96         bool ok=true;
     97         R(i,1,n+1)
     98         {
     99             if(!ok) break;
    100             R(j,1,n+1)
    101             {
    102                 if(i!=j && g[i][j]!=inf && ans==ans-path[i][j]+g[i][j])
    103                 {
    104                     ok=false;
    105                     break;
    106                 }
    107             }
    108         }
    109         if(ok)
    110             printf("%d\n",ans);
    111         else
    112             puts("Not Unique!");
    113     }
    114     return 0;
    115 }
  • 相关阅读:
    多项式回归学习笔记
    线性回归学习笔记
    CentOS6.9下安装python notebook
    CentOS 6.9下安装PostgreSQL
    区块链共识机制及其迭代
    比特币的区块结构解析
    区块链学习路线
    应用缓存的常见问题及解决
    阿里巴巴开源技术体系
    工程师进阶推荐十本书
  • 原文地址:https://www.cnblogs.com/Missa/p/2923026.html
Copyright © 2020-2023  润新知