zoukankan      html  css  js  c++  java
  • [USACO] 打井 Watering Hole

    题目描述

    Farmer John has decided to bring water to his N (1 <= N <= 300) pastures which are conveniently numbered 1..N. He may bring water to a pasture either by building a well in that pasture or connecting the pasture via a pipe to another pasture which already has water.

    Digging a well in pasture i costs W_i (1 <= W_i <= 100,000).

    Connecting pastures i and j with a pipe costs P_ij (1 <= P_ij <= 100,000; P_ij = P_ji; P_ii=0).

    Determine the minimum amount Farmer John will have to pay to water all of his pastures.

    POINTS: 400

    农民John 决定将水引入到他的n(1<=n<=300)个牧场。他准备通过挖若干井,并在各块田中修筑水道来连通各块田地以供水。在第i 号田中挖一口井需要花费W_i(1<=W_i<=100,000)元。连接i 号田与j 号田需要P_ij (1 <= P_ij <= 100,000 , P_ji=P_ij)元。

    请求出农民John 需要为使所有农场都与有水的农场相连或拥有水井所需要的钱数。

    题目解析

    一眼看上去很麻烦,但是只要想到了其实很简单,最小生成树而已。

    加一个点作为井,跑最小生成树,虽然不是很快但对于这道题绰绰有余了(110ms / 10*1s)

    思路好题

    Code

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    const int MAXN = 300 + 5;
    
    struct Edge {
        int from,to;
        int w;
        friend bool operator < (Edge x,Edge y) {
            return x.w < y.w;
        }
    } l[MAXN*MAXN];
    
    int n,ans;
    int fa[MAXN];
    int cnt;
    
    inline int find(int x) {
        if(fa[x] == x) return x;
        return fa[x] = find(fa[x]);
    }
    
    inline void add(int x,int y,int z) {
        cnt++;
        l[cnt].from = x;
        l[cnt].to = y;
        l[cnt].w = z;
        return;
    }
    
    int main() {
        scanf("%d",&n);
        int x;
        for(int i = 1;i <= n;i++) {
            scanf("%d",&x);
            add(i,n+1,x);
        }
        for(int i = 1;i <= n;i++) {
            for(int j = 1;j <= n;j++) {
                scanf("%d",&x);
                if(i == j) continue;
                add(i,j,x);
            }
        }
        for(int i = 1;i <= n+1;i++) fa[i] = i;
        sort(l+1,l+1+n*n);
        int num = 0;
        for(int i = 1;i <= n*n && num <= n;i++) {
            if(find(l[i].from) == find(l[i].to)) continue;
            num++; ans += l[i].w;
            fa[find(l[i].from)] = find(l[i].to);
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    关于 Lazy<T>
    silverlight 模仿淘宝预览图片
    自动安装silverlight,类似flash自动安装
    来说说mask吧
    笔试题n! 末尾0的个数
    VueCLI和脚手架(原创)
    REST构架风格介绍之一:状态表述转移(ZZ)
    VSS2005的配置(转载)
    ArcGIS9.2安装与.NET简单使用(zz 简单且有用)
    ASP.NET内置对象(7个)
  • 原文地址:https://www.cnblogs.com/floatiy/p/9720654.html
Copyright © 2011-2022 走看看