zoukankan      html  css  js  c++  java
  • POJ-1679 The Unique MST (判断最小生成树的唯一性)

    <题目链接>

    题目大意:

    给定一张无向图,判断其最小生成树是否唯一。

    解题分析:

    对图中每条边,扫描其它边,如果存在相同权值的边,则标记该边;用kruskal求出MST。

    如果MST中无标记的边,则该MST唯一;否则,在MST中依次去掉标记的边,再求MST,若求得MST权值和原来的MST 权值相同,则MST不唯一。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int M = 1e4+100;
    struct EDGE{
        int u,v,w;
        int eq,used,del;
    }edge[M];
    int n,m;
    int father[M];
    bool flag;
    bool cmp(EDGE a,EDGE b){
        return a.w<b.w;
    }
    int find(int x){
        if(father[x]!=x)father[x]=find(father[x]);
        return father[x];
    }
    int Kruscal(){
        for(int i=0;i<1e4+10;i++)father[i]=i;
        int sum=0,num=0;
        for(int i=0;i<m;i++){
            if(edge[i].del)continue;//如果该边被删除,则跳过
            int u=edge[i].u,v=edge[i].v,w=edge[i].w;
            if(find(u)!=find(v)){
                sum+=w,num++;
                if(flag)edge[i].used=1;//将第一次最小生成树的所有边标记
                father[find(v)]=find(u);
            }
            if(num>=n-1)break;
        }
        return sum;
    }
    int main(){
        int T;scanf("%d",&T);
        while(T--){
            scanf("%d%d",&n,&m);
            memset(edge,0,sizeof(edge));    //用memset能给edge内的所有变量初始化吗?
            for(int i=0;i<m;i++){
                scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
            }
            for(int i=0;i<m;i++){
                for(int j=0;j<m;j++){
                    if(i==j)continue;
                    if(edge[i].w==edge[j].w)edge[i].eq=1;//判断是否有和它权值相同的边
                }
            }
            sort(edge,edge+m,cmp);
            flag=true;
            int cnt=Kruscal();
            flag=false;
            bool fp=false;
            for(int i=0;i<m;i++){
                if(edge[i].eq&&edge[i].used){
                    edge[i].del=1;//如果这条边在第一次求的最小生成树中,并且还有与这条边权值相同的边,那么就试着删除这条边,再跑一遍最小生成树,看得到的权值总和是否与第一次的最小生成树相同
                    int res=Kruscal();
                    if(res==cnt){
                        fp=true;
                        printf("Not Unique!
    ");
                        break;
                    }
                    edge[i].del=0;
                }
            }
            if(!fp)printf("%d
    ",cnt);
        }
        return 0;
    }

    2018-10-01

  • 相关阅读:
    网络需求分析课堂作业
    工程招标与投标课堂作业
    burpsuite Pro下载安装及破解 | JDK安装和配置
    渗透测试环境的搭建
    web应用基础架构
    为Linux环境安装图形化界面
    Linux基本操作
    markdown语法教程(更新中)
    VMware导入和删除虚拟机文件
    Java求幂集与List的浅拷贝深拷贝问题
  • 原文地址:https://www.cnblogs.com/00isok/p/9735898.html
Copyright © 2011-2022 走看看