次最小生成树 模版

Posted

tags:

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

所谓次小生成树,顾名思义就是从生成树中取出的第二小的生成树。

我们在前面已经说过最小生成树的概念及代码实现了,所以接下来要说的次小生成树应该比较简单理解了。

求次小生成树的两种方法

1:首先求出最小生成树T,然后枚举最小生成树上的边,计算除了枚举的当前最小
生成树的边以外的所有边形成的最小生成树Ti,然后求最小的Ti就是次小生成树。
2:首先计算出最小生成树T,然后对最小生成树上任意不相邻的两个点 (i,j)
添加最小生成树以外的存在的边形成环,然后寻找i与j之间最小生成树上最长的边删去,
计算map[i][j](最小生成树以外存在的边) 与 maxd[i][j](最小生成树上最长的边)
差值,求出最小的来,w(T)再加上最小的差值就是次小生成树了。

 

给定一个图,询问该图的最小生成树与次小生成树是否一致。

 Kruscal实现版:

代码:

//Gang
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#define FOR(x,y,z) for(int x=y;x<=z;x++)
#define REP(x,y,z) for(int x=y;x>=z;x--)
#define ll long long
using namespace std;
int t,n,m,fa[10000],num,ans[10000];
int tot,bns,k,answer=99999999;
struct node
{
    int x,y,z;
} e[101*101];
int cmp(node a,node b)
{
    return a.z<b.z;
}
int find(int x)
{
    int p,temp;
    p=x;
    while(fa[x]!=x)
    {
        x=fa[x];
    }
    while(x!=p)
    {
        temp=fa[p];
        fa[p]=x;
        p=temp;
    }
    return x;
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        tot=0,bns=0;
        answer=99999999;
        memset(fa,0,sizeof(fa));
        memset(ans,0,sizeof(ans));
        FOR(i,1,m)
        scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z);
        sort(e+1,e+m+1,cmp);
        FOR(i,1,n)fa[i]=i;
        FOR(i,1,m)
        {
            int dx=find(e[i].x),dy=find(e[i].y);
            if(dx!=dy)
            {
                tot++;
                fa[dx]=dy;
                ans[tot]=i;
                         bns+=e[i].z;
            }
            if(tot==n-1)break;
        }
        FOR(i,1,tot)
        {
            k=0;
            num=0;
            FOR(j,1,n)
            fa[j]=j;
            sort(e+1,e+m+1,cmp);
            FOR(j,1,m)
            {
                if(j==ans[i])continue;
                int dx=find(e[j].x),dy=find(e[j].y);
                if(dx!=dy)
                {
                    fa[dx]=dy;
                    num++;
                    k+=e[j].z;
                }
                if(num==n-1)break;
            }
            if(num==n-1)answer=min(k,answer);
        }
        if(answer==bns)printf("Not Unique!\n");
        else printf("%d\n",bns);
    }
    return 0;
}

prim实现版

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int inf = 0x7fffffff;
const int size = 501;

int firstpath[size][size];
int secondpath[size][size];
int pre[size];
int d[size];
int tree[size];
int t=0;
bool flag[size];
int V,E;

int qmax(int x,int y)
{
   if(x>y)return x;
   else return y;
}

void prime(int u)
{
   int i,j;
   for(i=1;i<=V;++i)
    {
      flag[i]=false;
      d[i]=inf;
    }
   for(i=1;i<=V;++i)
    for(j=i;j<=V;++j)
     secondpath[i][j]=secondpath[j][i]=-1;
   t=0;
   tree[t++]=u;
   flag[u]=true;

   for(i=1;i<V;++i)
    {
       int min=inf;
       int k;
       for(j=1;j<=V;++j)
        {
           if(d[j]>firstpath[u][j])
            {
              d[j]=firstpath[u][j];
              pre[j]=u;
            }
           if(!flag[j] && d[j]<min)
            {
               min=d[j];
               k=j;
            }
        }

        for(j=0,u=k;j<t;++j)
         {
           secondpath[tree[j]][u]=qmax(secondpath[tree[j]][pre[u]],d[u]);
           secondpath[u][tree[j]]=secondpath[tree[j]][u];
         }
       firstpath[pre[u]][u]=firstpath[u][pre[u]]=inf;
       flag[u]=true;
       tree[t++]=u;
    }

   for(i=1;i<=V;++i)
    for(j=i+1;j<=V;++j)
     if(firstpath[i][j]!=inf && firstpath[i][j]==secondpath[j][i])
      {
        printf("Yes\n");
        return ;
      }
   printf("No\n");
}

int main()
{
   int i,T,j,x,y,z;
   scanf("%d",&T);
   while(T--)
    {
      scanf("%d%d",&V,&E);
      for(i=1;i<=V;++i)
       for(j=i;j<=V;++j)
        firstpath[i][j]=firstpath[j][i]=inf;
      for(i=0;i<E;++i)
       {
          scanf("%d%d%d",&x,&y,&z);
          firstpath[x][y]=firstpath[y][x]=z;
       }
      prime(1);
    }
   return 0;
}

 

以上是关于次最小生成树 模版的主要内容,如果未能解决你的问题,请参考以下文章

最小生成树(模版)

最小生成树 模版

次小生成树

XDOJ_1069_最小生成树

[学习-思考-探究]莫队算法 曼哈顿最小生成树与分块区间询问算法-3

严格次小生成树