zoukankan      html  css  js  c++  java
  • poj 1679 The Unique MST 【次小生成树+100的小数据量】

    题目地址:http://poj.org/problem?id=1679

    2
    3 3
    1 2 1
    2 3 2
    3 1 3
    4 4
    1 2 2
    2 3 2
    3 4 2
    4 1 2

    Sample Output

    3
    Not Unique!

    次小生成树学习博客:http://blog.csdn.net/niushuai666/article/details/6925258

    分析:T组数据,每组n个节点m条边。计算一下,最小生成树是不是独一无二的,如果是就输出最小生成树的权值和,否则输出Not Unique!(不是独一无二的)。
    先计算最小生成树,在计算次小生成树,判断两者的值是否相等!输入数据保证不存在重边。
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <math.h>
    #include <iostream>
    #include <string>
    #include <algorithm>
    #define N 110
    #define INF 0x3f3f3f3f
    
    using namespace std;
    int n, m;
    
    int map[N][N];
    bool used[N][N];
    int pre[N];
    bool vis[N];
    int dis[N];
    int Max[N][N];
    
    int prim()
    {
        int ans=0; int i, j;
        memset(vis, false, sizeof(vis));
        memset(used, false, sizeof(used));
        memset(dis, 0, sizeof(dis));
        memset(Max, 0, sizeof(Max));
    
        pre[1]=-1;
        vis[1]=true;
        for(i=2; i<=n; i++){
            dis[i]=map[1][i];
            pre[i]=1;
        }
    
        for(int k=0; k<n-1; k++){
            int mm=INF;
            int pos;
            for(i=1; i<=n; i++){
                if(!vis[i]&&mm>dis[i]){
                    mm=dis[i];
                    pos=i;
                }
            }
            ans+=mm; //在这可以加一条判断 如果找出来的mm==INF 说明不存在最小生成树
            vis[pos]=true;
    
            used[pos][pre[pos]]=true;
            used[pre[pos]][pos]=true;//pos与pre[pos]之间的边标记使用
            //update
            for(j=1; j<=n; j++){
                if(vis[j])
                    Max[j][pos]=Max[pos][j]=max(Max[j][pre[pos]], dis[pos] );
                if(!vis[j]&&dis[j]>map[pos][j])
                {
                    dis[j]=map[pos][j];
                    pre[j]=pos;
                }
            }
        }
        return ans;
    }
    int MST;
    int sed_mst()//计算次小生成树
    {
        int sed=INF;
        int i, j;
        for(i=1; i<=n; i++){
            for(j=i+1; j<=n; j++){
                if(map[i][j]!=INF && !used[i][j])
                {
                    sed=min(sed, MST+map[i][j]-Max[i][j]);
                }
            }
        }
        if(sed==INF) return -1;
        return sed;
    }
    
    int main()
    {
        int tg; scanf("%d", &tg);
        int i, j;
        while(tg--)
        {
            scanf("%d %d", &n, &m);
            for(i=1; i<=n; i++){
                for(j=1; j<=n; j++){
                    if(i==j) map[i][j]=0;
                    else map[i][j]=INF;
                }
            }//建图的初始化
    
            int u, v, w;
            for(i=0; i<m; i++){
                scanf("%d %d %d", &u, &v, &w);
                map[u][v]=map[v][u]=w;
            }
            MST=prim();
            //printf("%d
    ", MST);
    
            if(MST==sed_mst()){
                printf("Not Unique!
    ");
            }else{
                printf("%d
    ", MST);
            }
        }
        return 0;
    }
    

    kruskal算法实现:

    http://www.cnblogs.com/wally/archive/2013/02/03/2890460.html  

    (用那个人的代码提交到poj的这道题,耗时比上面的prim号高不少~~~)

    
    
  • 相关阅读:
    【BZOJ 4151 The Cave】
    【POJ 3080 Blue Jeans】
    【ZBH选讲·树变环】
    【ZBH选讲·拍照】
    【ZBH选讲·模数和】
    【CF Edu 28 C. Four Segments】
    【CF Edu 28 A. Curriculum Vitae】
    【CF Edu 28 B. Math Show】
    【CF Round 439 E. The Untended Antiquity】
    【CF Round 439 C. The Intriguing Obsession】
  • 原文地址:https://www.cnblogs.com/yspworld/p/4744053.html
Copyright © 2011-2022 走看看