zoukankan      html  css  js  c++  java
  • Light OJ 1029- Civil and Evil Engineer (图论-最小生成树)

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1029

    题目大意:一个发电站,给n座房子供电, 任意房子之间有电线直接或者间接相连接, 现在想知道需要连接这些房子花费的平均电线长度。平均电线长度 = (最长电线长度 + 最短电线长度)/ 2;

    解题思路:裸的最小生成树

    代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1003;
    struct edge
    {
        int s, t, l;
        edge() {}
        edge(int s, int t, int l):s(s), t(t), l(l) {}
    };
    vector<edge>vec;
    int par[N], Rank[N];
    int n;
    
    void init()
    {
        for(int i=0; i<=n; ++ i)
            par[i] = i, Rank[i] = 0;
    }
    
    int Find(int x)
    {
        if(par[x] == x)
            return x;
        else
            return par[x] = Find(par[x]);
    }
    
    void unite(int x, int y)
    {
        x = Find(x), y = Find(y);
        if(x == y)
            return ;
    
        if(Rank[x] < Rank[y])
            par[x] = y;
        else
        {
            par[y] = x;
            if(Rank[x] == Rank[y])
                Rank[x] ++;
        }
    }
    
    bool same(int x, int y)
    {
        return Find(x) == Find(y);
    }
    
    bool cmp(const edge &a, const edge &b)
    {
        return a.l < b.l;
    }
    
    bool Cmp(const edge &a, const edge &b)
    {
        return a.l > b.l;
    }
    
    int kruskal(int m)
    {
        init();
        if(m == 1)
            sort(vec.begin(), vec.end(), cmp);
        else
            sort(vec.begin(), vec.end(), Cmp);
        int res = 0;
        for(int i=0; i<vec.size(); ++ i)
        {
            edge e = vec[i];
            if(!same(e.s, e.t))
            {
                unite(e.s, e.t);
                res += e.l;
            }
        }
        return res;
    }
    
    void solve(int cases)
    {
        scanf("%d", &n);
        vec.clear();
        while(1)
        {
            int s, t, l;
            scanf("%d%d%d", &s, &t, &l);
            if((s || t || l) == false)
                break;
            vec.push_back(edge(s, t, l));
        }
    
        int ans = 0;
        ans += kruskal(1);
        ans += kruskal(2);
        if(ans & 1)
            printf("Case %d: %d/%d
    ", cases, ans, 2);
        else
            printf("Case %d: %d
    ", cases, ans/2);
    
    }
    
    int main()
    {
        int t;
        scanf("%d", &t);
        for(int i=1; i<=t; ++ i)
            solve(i);
        return 0;
    }
    View Code
  • 相关阅读:
    题解:luoguP1070 道路游戏(DP)
    题解:luoguP2577【ZJOI2005】午餐(DP)
    题解:bzoj1801: [Ahoi2009]chess 中国象棋
    题解:bzoj1878: [SDOI2009]HH的项链
    SpringBoot静态资源文件 lion
    简要的Log4Net 应用配置
    Web Service 初级教程
    log4Net 动态改变写入文件
    Ornament 类型资源权限
    JQuery 引发两次$(document).ready事件
  • 原文地址:https://www.cnblogs.com/aiterator/p/6035079.html
Copyright © 2011-2022 走看看