zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    poj 3666 Making the Grade
    poj 3186 Treats for the Cows (区间dp)
    hdu 1074 Doing Homework(状压)
    CodeForces 489C Given Length and Sum of Digits...
    CodeForces 163A Substring and Subsequence
    CodeForces 366C Dima and Salad
    CodeForces 180C Letter
    CodeForces
    hdu 2859 Phalanx
    socket接收大数据流
  • 原文地址:https://www.cnblogs.com/ramanujan/p/3364315.html
Copyright © 2011-2022 走看看