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

    题意:构成MST是否唯一

    思路:

    问最小生成树是否唯一。我们可以先用Prim找到一棵最小生成树,然后保存好MST中任意两个点i到j的这条路径中的最大边的权值Max[i][j],如果我们能找到一条边满足:他不是最小生成树中的边,并且它的权值等于Max[i][j],那么他就可以代替MST中的这条边,所以MST不唯一。

    次小生成树总结

    代码:

    #include<cmath>
    #include<stack>
    #include<queue>
    #include<string>
    #include<vector>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    const int N = 100+5;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    int n,m;
    int mp[N][N],dis[N],pre[N];
    bool vis[N];
    int Max[N][N];  //最大权值边
    bool is[N][N];   //是否在MST中
    
    void init(){
        int x,y,w;
        memset(mp,INF,sizeof(mp));
        for(int i = 0;i < m;i++){
            scanf("%d%d%d",&x,&y,&w);
            mp[x][y] = mp[y][x] = w;
        }
        memset(vis,false,sizeof(vis));
        vis[1] = true;
        for(int i = 2;i <= n;i++){
            dis[i] = mp[i][1];
            pre[i] = 1;
        }
    }
    void Prim(){
        int mincost = 0;
        memset(Max,0,sizeof(Max));
        memset(is,false,sizeof(is));
        for(int i = 1;i <= n - 1;i++){
            int MIN = INF;
            int point;
            for(int j = 1;j <= n;j++){
                if(!vis[j] && dis[j] < MIN){
                    MIN = dis[j];
                    point = j;
                }
            }
            vis[point] = true;
            mincost += MIN;
            is[point][pre[point]] = is[pre[point]][point] = true;   //在MST中
            for(int j = 1;j <= n;j++){
                if(vis[j] && j != point){   //在MST中
                    Max[j][point] = Max[point][j] = max(Max[pre[point]][j],dis[point]);
                    //更新j到point的最大权值边
                }
                if(!vis[j] && dis[j] > mp[j][point]){
                    pre[j] = point;
                    dis[j] = mp[j][point];
                }
            }
        }
        //判断MST是否唯一
        for(int i = 1;i <= n;i++){
            for(int j = 1;j < i;j++){
                if(mp[i][j] != INF && !is[i][j]){
                    if(mp[i][j] == Max[i][j]){
                        printf("Not Unique!
    ");
                        return;
                    }
                }
            }
        }
        printf("%d
    ",mincost);
    }
    int main() {
        int T;
        scanf("%d",&T);
        while(T--){
            scanf("%d%d",&n,&m);
            init();
            Prim();
        }
        return 0;
    }
    


  • 相关阅读:
    达梦数据库还原
    达梦数据库备份-Quartz定时任务备份
    达梦数据库备份-手动备份
    Hadoop集群分布式安装
    echarts实现group关系图案例
    U盘安装windows系统
    GC垃圾回收机制
    form表单提交方式实现浏览器导出Excel
    数据分析-信用卡反欺诈模型
    机器学习-SVM
  • 原文地址:https://www.cnblogs.com/KirinSB/p/9408779.html
Copyright © 2011-2022 走看看