• UVA 10600 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


    ----------

    一个裸的次小生成树,没什么好说的,我肯定做麻烦了

    ----------

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <cmath>
    using namespace std;
    
    const int INF=0x3f3f3f3f;
    const int maxn=211;
    const int maxm=21111;
    const double eps=1e-12;
    const double OO=1e100;
    
    struct Road{
        int u,v;
        int w;
        Road(){}
        Road(int u,int v,int w){
            this->u=u;
            this->v=v;
            this->w=w;
        }
        bool operator<(const Road& rhs) const{
            return w<rhs.w;
        }
    };
    
    class DisjointSet{
    private:
        int pa[maxn];
        int n;
    public:
        void makeSet(int n){
            this->n=n;
            for (int i=0;i<=n;i++) pa[i]=i;
        }
        int findSet(int x){
            if (x!=pa[x]) pa[x]=findSet(pa[x]);
            return pa[x];
        }
        void unionSet(int x,int y){
            x=findSet(x);
            y=findSet(y);
            if (x!=y) pa[x]=y;
        }
    }disjointSet;
    
    class Graph{
    private:
        struct EdgeNode{
            int to;
            int w;
            int next;
        };
        int head[maxn],edge,n;
        EdgeNode edges[maxm*2];
        int maxCost[maxn][maxn];
        void dfsCost(int s,int u,int pa){
            for (int i=head[u];i!=-1;i=edges[i].next){
                int v=edges[i].to;
                int w=edges[i].w;
                if (v==pa) continue;
                maxCost[s][v]=maxCost[s][u];
                if (maxCost[s][v]<w) maxCost[s][v]=w;
                dfsCost(s,v,u);
            }
        }
    public:
        void init(int n){
            this->n=n;
            memset(head,-1,sizeof(int)*(n+1));
            edge=0;
        }
        void addedge(int u,int v,int w){
            edges[edge].w=w,edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
        }
        void findMaxCost(){
            for (int i=1;i<=n;i++)
                for (int j=1;j<=n;j++)
                    maxCost[i][j]=0;
            for (int i=1;i<=n;i++){
                dfsCost(i,i,-1);
            }
        }
        int getMaxCost(int x,int y){
            return maxCost[x][y];
        }
    }tree;
    
    vector<Road>road;
    
    int n,m;
    int minTree;
    bool can[maxn][maxn];
    
    void initializer(){
        memset(can,0,sizeof(can));
        disjointSet.makeSet(n);
        road.clear();
        minTree=0;
        tree.init(n);
    }
    
    void input(){
        for (int i=0;i<m;i++){
            int a,b,w;
            scanf("%d%d%d",&a,&b,&w);
            road.push_back(Road(a,b,w));
        }
    }
    
    void Kruskal(){
        sort(road.begin(),road.end());
        for (vector<Road>::iterator it=road.begin();it!=road.end();it++){
            int u=it->u;
            int v=it->v;
            int w=it->w;
            if (disjointSet.findSet(u)!=disjointSet.findSet(v)){
                minTree+=w;
                disjointSet.unionSet(u,v);
                tree.addedge(u,v,w);
                tree.addedge(v,u,w);
                can[u][v]=can[v][u]=true;
            }
        }
        tree.findMaxCost();
    }
    void solve(){
        int ans=INF;
        for (vector<Road>::iterator it=road.begin();it!=road.end();it++){
            int u=it->u;
            int v=it->v;
            int w=it->w;
            if (!can[u][v]){
                ans=min(ans,minTree-tree.getMaxCost(u,v)+w);
            }
        }
        printf("%d %d
    ",minTree,ans);
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while (T--){
            scanf("%d%d",&n,&m);
            initializer();
            input();
            Kruskal();
            solve();
        }
        return 0;
    }
    


    ----------

  • 相关阅读:
    git提交到了错误的分支,如何解决
    js使用 isNumber() 判断是否是数字,要注意NaN
    prettier 出现 Couldn't resolve parser "babylon" 错误的解决方法
    在AWS CloudWatch中使用Logs Insights查询错误日志
    腾讯智能对话平台TBP 返回的数据结构
    python 中在使用f string 格式化字符串时出现ValueError: Invalid format specifier 的一种原因
    冒泡排序
    第一次摸底考试总结
    用for循环打印99乘法表
    数据库编写 数据库常用约束
  • 原文地址:https://www.cnblogs.com/cyendra/p/3681569.html
Copyright © 2020-2023  润新知