zoukankan      html  css  js  c++  java
  • POJ 3228 [并查集]

    题目链接:【http://poj.org/problem?id=3228】

    题意:给出n个村庄,每个村庄有金矿和仓库,然后给出m条边连接着这个村子。问题是把所有的金矿都移动到仓库里所要经过的路径的最大值的最小值。

    题解:贪心,把边排序,然后从小到大加边,如果加到某一条边之后,金矿都可以移动到仓库了,那么这条边就是结果。首先明白,如果一些边连接的一些村庄的仓库的总容量大于总金矿数,那么这些村庄的金矿就可以全部移动到仓库里了。如果在从小到大加边的时候形成了环,那么这条边可以不要(加进去也不会影响结果),然后用并查集维护就可以了,注意:在用并查集维护的时候,记得把仓库和金矿都移动到根节点,这样便于判断是否已经满足了情况了。

    //#include<bits/stdc++.h>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    typedef long long LL;
    using namespace std;
    const int maxn = 250;
    struct node
    {
        int st, ed, dis;
        bool operator < (const node T) const
        {
            return dis < T.dis;
        }
    } E[maxn * maxn];
    int g[maxn], h[maxn], N, M;
    int f[maxn];
    int Find(int u)
    {
        if(u == f[u]) return f[u];
        else return f[u] = Find(f[u]);
    }
    void adde(int u, int v)
    {
        f[u] = v;
        h[v] += h[u];
        h[u] = 0;
        g[v] += g[u];
        g[u] = 0;
    }
    bool check()
    {
        for(int i = 1; i <= N; i++)
        {
            int u = Find(i);
            if(h[u] < g[u]) return false;
        }
        return true;
    }
    int main ()
    {
        while(~scanf("%d", &N), N)
        {
            for(int i = 1; i <= N; i++)
                f[i] = i;
            int sumg = 0, sumh = 0;
            for(int i = 1; i <= N; i++)
            {
                scanf("%d", &g[i]);
                sumg += g[i];
            }
            for(int i = 1; i <= N; i++)
            {
                scanf("%d", &h[i]);
                sumh += h[i];
            }
            if(sumh < sumg)
            {
                printf("No Solution
    ");
                continue;
            }
            scanf("%d", &M);
            for(int i = 1; i <= M; i++)
                scanf("%d%d%d", &E[i].st, &E[i].ed, &E[i].dis);
            sort(E + 1, E + 1 + M);
            int ans = 0;
            if(check())
            {
                printf("%d
    ", ans);
                continue;
            }
            for(int i = 1; i <= M; i++)
            {
                int u = Find(E[i].st);
                int v = Find(E[i].ed);
                if(u == v) continue;
                adde(u, v);
                ans = E[i].dis;
                if(check()) break;
            }
            if(check()) printf("%d
    ", ans);
            else printf("No Solution
    ");
        }
        return 0;
    }
    想的太多,做的太少。
  • 相关阅读:
    webpack4.0在项目中的安装配置
    Java调用开源GDAL解析dxf成shp,再调用开源GeoTools解析shp文件
    VUE-CLI3.0组件封装打包使用
    鼠标光标在input框,单击回车键后防止页面刷新的问题
    MapBox GL加载天地图以及加载导航控件
    web前端监控视频的展示
    css外部字体库文件的引用
    IIS上部署的程序,PLSQL能连上数据库,系统登录报错
    部署在IIS上的程序,可以找到文件夹,能看到文件却报404
    继承
  • 原文地址:https://www.cnblogs.com/pealicx/p/6707487.html
Copyright © 2011-2022 走看看