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号高不少~~~)

    
    
  • 相关阅读:
    python模拟android屏幕高频点击工具
    android adb shell and monkey 学习记录
    appium+python环境搭建
    python监控接口请求
    JetBrains Pycharm 破解+汉化
    loadrunner调用jar包方法
    python抢小米6自动化脚本
    CDlinux制作U盘启动盘,打造自己的口袋系统
    无线渗透测试之wifi密码破解
    测试-test1
  • 原文地址:https://www.cnblogs.com/yspworld/p/4744053.html
Copyright © 2011-2022 走看看