The Unique MST POJ - 1679 次小生成树prim

Posted ttttttttrx

tags:

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

求次小生成树思路: 先把最小生成树求出来  用一个Max[i][j] 数组把  i点到j 点的道路中 权值最大的那个记录下来 used数组记录该条边有没有被最小生成树使用过   把没有使用过的一条边加入最小生成树必然回形成一条回路   在这条回路中减去 除加入的边的权值最大的一条边  原图必然保持连通  (如果此时 权值最大的边和新加入的边权值相同  则存在 不同的最小生成树) 把每一条边加入再删除后 即可得出次小生成树 

参考了: https://blog.csdn.net/qq_33951440/article/details/53084248  

     https://blog.csdn.net/li1615882553/article/details/80011884

     https://www.cnblogs.com/kuangbin/p/3147329.html

 

#include <cstdio>
#include <cmath>
#include <algorithm>
#include<vector>
#include<iostream>
#include<cstring>
int ans;
const int maxn=1000+10;
const int INF=100000000;
int x[maxn],y[maxn];
int cost[maxn][maxn];
int pre[maxn];
int lowc[maxn];
int Max[maxn][maxn];
int vis[maxn];
int parent[maxn];
int used[maxn][maxn];
using namespace std;
int prim(int cost[][maxn],int n){
    int ans=0;
       memset(vis,false,sizeof(vis));
    memset(Max,0,sizeof(Max));
    memset(used,false,sizeof(used));
    vis[0]=1;
    pre[0]=-1;
    for(int i=1;i<n;i++){
        lowc[i]=cost[0][i];//刚开始只有v0在生成树中  生成树和不在生成树的距离 就是v0和 其他点的距离
        pre[i]=0;
    }
    for(int i=1;i<n;i++){
        int minc=INF;
        int p=-1;
        for(int j=0;j<n;j++){
            if(!vis[j]&&minc>lowc[j]){//找出到树最短的变
                minc=lowc[j];
                  p=j;
            }
        }
        if(p==-1)return -1; //不连通 
        ans+=minc;
        vis[p]=1;
        used[p][pre[p]]=used[pre[p]][p]=1;  //该边设置为已使用
        for(int j=0;j<n;j++){
            if(vis[j])Max[j][p]=Max[p][j]=max(Max[j][pre[p]],minc);//更新 j到p 的最大权值的边
            if(!vis[j]&&lowc[j]>cost[p][j]){
                lowc[j]=cost[p][j]; //更新树到点的最短距离
                pre[j]=p;//j点如果要进树 连p点 所以p就是j的父结点
            }
        }
    }
    return ans;

}


int smst(int cost[][maxn],int n){ //计算是否可以删除一条边  仍得到所有边权值不变
    int minnum=INF;
    for(int i=0;i<n;i++){
        for(int j=i+1;j<n;j++){
            if(cost[i][j]!=INF&&!used[i][j]){
                minnum=min(minnum,ans+cost[i][j]-Max[i][j]);
            }

        }
    }
    return minnum;
}

int main()
{
    int t;
    cin>>t;
    while(t--){
        int n,m;
        scanf("%d%d",&n,&m);
        int u,v,w;
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(i==j)cost[i][j]=0;
                else cost[i][j]=INF;
            }
        }
        while(m--){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            u--,v--;
            cost[u][v]=cost[v][u]=w;
        }
        ans=prim(cost,n);
        if(ans==smst(cost,n)){
                printf("Not Unique!
");
        }
        else  printf("%d
",ans);

    }
    return 0;
}

 

以上是关于The Unique MST POJ - 1679 次小生成树prim的主要内容,如果未能解决你的问题,请参考以下文章

[2016-01-27][POJ][1679][The Unique MST]

POJ 1679 The Unique MST

POJ——T1679 The Unique MST

POJ1679 The Unique MST —— 次小生成树

POJ-1679 The Unique MST---判断最小生成树是否唯一

POJ1679 The Unique MST