• uva 10600 次小生成树


    Problem A

    ACM contest and Blackout

    In order to prepare the “The First National ACM School Contest”(in 20??) the major of the city decided to provide all the schools with a reliable source of power. (The major is really afraid of blackoutsJ). So, in order to do that, power station “Future” and one school (doesn’t matter which one) must be connected; in addition, some schools must be connected as well.

    You may assume that a school has a reliable source of power if it’s connected directly to “Future”, or to any other school that has a reliable source of power. You are given the cost of connection between some schools. The major has decided to pick out two the cheapest connection plans – the cost of the connection is equal to the sum of the connections between the schools. Your task is to help the major – find the cost of the two cheapest connection plans.

    Input

    The Input starts with the number of test cases, T (1£T£15) on a line. Then T test cases follow. The first line of every test case contains two numbers, which are separated by a space, N (3£N£100) the number of schools in the city, and M the number of possible connections among them. Next M lines contain three numbers Ai, Bi, Ci , where Ci  is the cost of the connection (1£Ci£300) between schools Ai  and Bi. The schools are numbered with integers in the range 1 to N.

    Output

    For every test case print only one line of output. This line should contain two numbers separated by a single space - the cost of two the cheapest connection plans. Let S1 be the cheapest cost and S2 the next cheapest cost. It’s important, that S1=S2 if and only if there are two cheapest plans, otherwise S1£S2. You can assume that it is always possible to find the costs S1 and S2..

    Sample Input

    Sample Output

    2

    5 8

    1 3 75

    3 4 51

    2 4 19

    3 2 95

    2 5 42

    5 4 31

    1 2 9

    3 5 66

    9 14

    1 2 4

    1 8 8

    2 8 11

    3 2 8

    8 9 7

    8 7 1

    7 9 6

    9 3 2

    3 4 7

    3 6 4

    7 6 2

    4 6 14

    4 5 9

    5 6 10

    110 121

    37 37

    Problem source: Ukrainian National Olympiad in Informatics 2001

    Problem author: Shamil Yagiyayev

    Problem submitter: Dmytro Chernysh

    Problem solution: Shamil Yagiyayev, Dmytro Chernysh, K M Hasan

     

    求两棵最小的生成树权值,第一个显然mst,第二个用n^2 dfs求出任意两点间最大边权,然后枚举没有在mst中的边求次小mst即可

    1A代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    #include<map>
    
    using namespace std;
    
    #define LL long long
    #define ULL unsigned long long
    #define UINT unsigned int
    #define MAX_INT 0x7fffffff
    #define cint const int
    #define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
    #define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
    
    #define MAXN 111
    #define MAXM 11111
    #define INF 100000000
    
    struct edge{
        int u, v, d;
        bool operator < (const edge &rhs)const{
            return d < rhs.d;
        }
    }e[MAXM];
    vector<int> g[MAXN];
    int n, m;
    
    int p[MAXN];
    int finds(int x){
        if(p[x]==-1) return x;
        else return (p[x]=finds(p[x]));
    }
    
    bool vis[MAXM];
    int w[MAXN][MAXN];
    int mst(){
        fill_n(p+1, n, -1);
        fill_n(vis, m, false);
        for(int i=1; i<=n; i++) g[i].clear();
        sort(e, e+m);
    
        int ans=0;
        for(int i=0, j=0; i<m; i++){
            int x = e[i].u, y = e[i].v, d = e[i].d;
            int fx = finds(x), fy = finds(y);
            if(fx!=fy){
                p[fx]=fy;
                ans+=d;                 vis[i]=true;
                g[x].push_back(y);      w[x][y]=w[y][x]=d;
                g[y].push_back(x);
                if(++j==n-1) break;
            }
        }
        return ans;
    }
    
    int maxcst[MAXN][MAXN];
    vector<int> pre;
    //bool viv[MAXN];
    
    void dfs(int u, int fa){
    //    viv[u]=true;
        for(int i=0; i<pre.size(); i++){
            int v = pre[i], d = w[fa][u];
            maxcst[u][v]=maxcst[v][u]=
            MAX(d, maxcst[fa][v]);
        }
        pre.push_back(u);
        for(int i=0; i<g[u].size(); i++) if(fa!=g[u][i])
            dfs(g[u][i], u);
    }
    
    int main(){
    //    freopen("C:\Users\Administrator\Desktop\in.txt","r",stdin);
        int T;
        scanf(" %d", &T);
        while(T--){
            int i;
            scanf(" %d %d", &n, &m);
            for(i=0; i<m; i++){
                int u, v, w;
                scanf(" %d %d %d", &u, &v, &w);
                if(u!=v) e[i]=(edge){u, v, w};       // - -
            }
    
            int fir = mst();
            for(i=1; i<=n; i++) fill_n(maxcst[i]+1, n, -1);
    //        fill_n(viv+1, n, false);
            pre.clear();
    //        printf("%d
    ", fir);
            dfs(1, -1);
            int sec = INF;
            for(i=0; i<m; i++) if(!vis[i]){
                int u = e[i].u, v = e[i].v, d = e[i].d;
                sec=MIN(sec, fir-maxcst[u][v]+d);
    //            cout<<"^^^^^^^^^^^^^^^^^^^^^^"<<endl;
    //            cout<<(fir-maxcst[u][v]+d)<<endl;
    //            cout<<maxcst[u][v]<<endl;
    ////            cout<<e[i].u<<' '<<e[i].v<<' '<<e[i].d<<endl;
    //            cout<<"&&&&&&&&&&&&&&&&&&&&&&&"<<endl;
            }
            printf("%d %d
    ", fir, sec);
        }
        return 0;
    }
    
  • 相关阅读:
    iOS常用第三方库之Masonry
    iOS超全面试题,面试前看一看,不错
    自学安卓练习作品单词APP(1)-安卓的hello word与有道字典防爬虫破解
    shrio的rememberMe不起作用
    上传组件uploadify在spring中返回406 / Not Acceptable 问题解决
    由max_allowed_packet引发的mysql攻防大战
    又到毕业季你为什么没有工作
    mavan下scala编译中文乱码的问题.以及内存溢出问题解决
    @RestController失效
    BeanInstantiationException: Failed to instantiate [java.time.LocalDateTime]
  • 原文地址:https://www.cnblogs.com/ramanujan/p/3364315.html
Copyright © 2020-2023  润新知