• 次小生成树


    次小生成树,顾名思义,求最小生成树之外的最小生成树,即倒数第二小的生成树。

    先利用prim求出最小生成树。并将最小生成树任意两点之间路径当中的权值最大的那一条找出来,为什么要找最大的呢,因为生成树再加入一条边之后一定构成了回路,那么肯定要去掉这个回路当中一条边才是生成树,那么,怎么去边才是次小的,那就去掉除了刚刚添加的一条边之外回路当中权值最大的一个,所以留下的就是最小的。

    题目:POJ1679

    题意:给定图,让求它的最小生成树是否唯一。如果唯一的话输出最小生成树的权值和,否则输出Not Unique!

    #include <iostream>
    #include <stdio.h>
    #define MAX 0x3f3f3f3f
    const int N = 105;
    using namespace std;
    int mp[N][N],vis[N],dis[N],st[N],max1[N][N],pre[N];
    int n,m,ans;
    void Init(){
        for(int i = 0;i < N; i++)
            for(int j = 0; j < N; j++){
                mp[i][j] = mp[j][i] = MAX;
                max1[i][j] = max1[j][i] = 0;
            }
        fill(vis,vis+N,0);
    }
    void prim(){
        int min_value,top = 0,k;
        vis[1] = 1;
        ans = 0;
        for(int i = 1;i <= n; i++)
        {
            pre[i] = 1;
            dis[i] = mp[1][i];
        }
        dis[1] = 0;
        st[top++] = 1;//保存MST的结点
        for(int i = 1;i <= n; i++){
            min_value = MAX;
            for(int j = 1; j <= n; j++){
                if(!vis[j]&&min_value>dis[j])
                    min_value = dis[k = j];
            }
            if(min_value==MAX)
                    break;
            vis[k] = 1;
            ans += min_value;
            for(int j = 0;j < top; j++)
                max1[st[j]][k] = max1[k][st[j]] = max(min_value,max1[st[j]][pre[k]]);//新加入点到MST各点路径最大值
            st[top++] = k;//保存MST的结点
            for(int j = 1;j<=n;j++)
                if(!vis[j]&&dis[j]>mp[k][j])
                {
                    dis[j] = mp[k][j];
                    pre[j] = k;//记录直接前驱
                }
        }
    }
    int main()
    {
        int t;
        cin>>t;
        while(t--){
            Init();
            int s,e,value;
            cin>>n>>m;
            for(int i = 0;i < m;i++)
            {
                cin>>s>>e>>value;
                mp[s][e] = mp[e][s] = value;
            }
            prim();
            int minn = MAX;
            for(int i = 1; i <= n; i++)枚举MST以外的边
                for(int j = 1;j <= n; j++)
                    if(i!=j&&i!=pre[j]&&j!=pre[i])
                        minn = min(minn,mp[i][j]-max1[i][j]);
            if(minn)
                cout<< ans <<endl;
            else
                cout<< "Not Unique!"<<endl;
        }
        return 0;
    }
    宝剑锋从磨砺出 梅花香自苦寒来
  • 相关阅读:
    FusionInsight HD组件介绍
    Hive与HBase的区别与联系
    SSD与HDD、HHD的区别
    RAID 2.0 技术(块虚拟化技术)
    Fusionstorage的逻辑架构
    介绍一下什么是“虚拟化”
    介绍一下什么是“云计算”
    介绍一下什么是“存储器”
    介绍一下什么是“服务器”
    SAS与SATA的区别
  • 原文地址:https://www.cnblogs.com/GHzcx/p/8252400.html
Copyright © 2020-2023  润新知