zoukankan      html  css  js  c++  java
  • poj 1679 The Unique MST(次小生成树)

    题意:判断最小生成树是否唯一。

    思路:求出次小生成树,如果与最小生成树相等,则不唯一。

    ps博客

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    /*
    求最小生成树时,用数组Max[i][j]来表示MST中i到j路径中的最大权边
    求完后,直接枚举所有不在MST中的边,替换掉最大权边的边,更新答案
    点编号从0开始
    */
    const int MAXN=110;
    const int INF=0x3f3f3f3f;//1061109567
    bool vis[MAXN];
    int lowc[MAXN];
    int pre[MAXN];
    int Max[MAXN][MAXN];//Max[i][j]表示在最小生成树中从i到j的路径中的最大边权
    bool used[MAXN][MAXN];
    int cost[MAXN][MAXN];
    int ans;
    
    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]=true;
        pre[0]=-1;
        for(int i=1;i<n;i++){
            lowc[i]=cost[0][i];
            pre[i]=0;
        }
        lowc[0]=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(minc==INF)return -1;
            ans+=minc;
            vis[p]=true;
            used[p][pre[p]]=used[pre[p]][p]=true;
            for(int j=0;j<n;j++){
                if(vis[j])Max[j][p]=Max[p][j]=max(Max[j][pre[p]],lowc[p]);
                if(!vis[j]&&lowc[j]>cost[p][j]){
                    lowc[j]=cost[p][j];
                    pre[j]=p;
                }
            }
        }
        return ans;
    }
    
    int smst(int cost[][MAXN],int n){
        int Min=INF;
        for(int i=0;i<n;i++)
            for(int j=i+1;j<n;j++)
                if(cost[i][j]!=INF&&!used[i][j]){
                    Min=min(Min,ans+cost[i][j]-Max[i][j]);
                }
        if(Min==INF)return -1;//不存在
        return Min;
    }
    
    int main(){
        int t,i,j;
        int n,m;
        int u,v,w;
        scanf("%d",&t);
        while(t--){
            scanf("%d%d",&n,&m);
            for(i=0;i<n;i++)
                for(j=0;j<n;j++){
                    if(i==j)cost[i][j]=0;
                    else cost[i][j]=INF;
                }
            while(m--){
                scanf("%d%d%d",&u,&v,&w);
                u--;v--;
                cost[u][v]=cost[v][u]=w;
            }
            ans=prim(cost,n);
            if(ans==-1)printf("Not Unique!
    ");
            else if(ans==smst(cost,n))printf("Not Unique!
    ");
            else printf("%d
    ",ans);
        }
        return 0;
    }


  • 相关阅读:
    Java 中几种常用的线程池
    阿里巴巴java工程师面试经验详情
    设计模式-备忘录模式
    设计模式-职责链模式
    设计模式-中介者模式
    设计模式-解释器模式
    设计模式-观察者模式
    设计模式-迭代器模式
    设计模式-命令模式
    设计模式-模板方法模式
  • 原文地址:https://www.cnblogs.com/zswbky/p/8454142.html
Copyright © 2011-2022 走看看