zoukankan      html  css  js  c++  java
  • 新的开始( [USACO08OCT]打井Watering Hole)

    新的开始
    (newstart.pas/c/cpp)
    【 题目描述】
    话说小 FF 在经历了上次“寻找古代王族遗产” 的探险后, 成为了世界上最伟大的探险
    家并拥有了一大笔财富。 当然他不能坐吃山空, 必须创造财富!! 于是他买下了传说中的
    GreedIsland 并优先发展那里的采矿业„„他还将其称为 GreedIsland 的“ NewBe_One” 计划。
    发展采矿业当然首先得有矿井, 小 FF 花了上次探险获得的千分之一的财富请人在岛上
    挖了 N 口矿井, 但他似乎忘记考虑的矿井供电问题„„
    为了保证电力的供应, 小 FF 想到了两种办法:
    1、 在这一口矿井上建立一个发电站, 费用为 v( 发电站的输出功率可以供给任意多个
    矿井)。
    2、 将第 i 口矿井与已经有电力供应的第 j 口矿井之间建立电网的费用为 p[i,j]。
    小 FF 希望身为”NewBe_One”计划首席工程师的你帮他想出一个保证所有矿井电力供应的最
    小花费。
    【 输入格式】
    第一行一个整数 N,表示矿井总数。
    第 2~N+1 行, 每行一个整数, 第 i 个数 v[i]表示在第 i 口矿井上建立发电站的费用。 接
    下来为一个 N×N 的矩阵 P, 其中 p[i,j]表示在第 i 口矿井和第 j 口矿井之间建立电网的费用
    ( 数据保证有 p[i,j]=p[j,i],且 p[i,i]=0)。
    【 输出格式】
    输出共一行一个整数, 表示让所有矿井获得充足电能的最小花费。
    【 输入样例】
    4 5 4 4 3 0
    2 2 2
    2 0 3 3
    2 3 0 4
    2 3 4 0
    【 输出样例】
    9
    【 输出样例说明】
    小 FF 可以选择在 4 号矿井建立发电站然后把所有矿井都与其建立电网, 总花费是
    3+2+2+2=9。
    【 数据规模】
    对于 30%的数据: 1≤N≤50;
    对于 100%的数据: 1≤N≤300; 1≤v[i],p[i,j]≤10^5;

    这题看着没有任何头绪,但其实只是最小生成树。

    这题看着没有任何头绪,但其实只是最小生成树。

    这题看着没有任何头绪,但其实只是最小生成树。
    先看张图!
    这里写图片描述
    我们可以这么想,岛上有一座另外的发电站p。
    在x这个矿井造一个发电站,消耗w[i],就相当于x点到p点的消耗经费为w[i]
    于是就可以构筑出上面那张图,上图求所有点相连的最小值不就是最小生成树吗?

    code:

    #include<bits/stdc++.h>
    using namespace std;
    int i,j,k,n,m,tot,ans,fa[305],w[305],f[305][305],top,re;
    int read(){
        char c;while(c=getchar(),(c<'0'||c>'9')&&c!='-');
        int x=0,y=1;if(c=='-') y*=-1;else x=c-'0';
        while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0'; 
        return x*y;
    }
    int find(int x){
        if(fa[x]!=x) fa[x]=find(fa[x]);
        return fa[x];
    }
    void unionn(int x,int y){
        x=find(x);y=find(y);
        if(x>y) fa[x]=y;
        else fa[y]=x;
    }
    struct node{
        int a,b,len;
    }a[100005];
    int cmp(node a,node b){
        if(a.len<b.len) return 1;
        else return 0;
    }
    int main()
    {
        n=read();re=0;
        for(int i=1;i<=n;i++) w[i]=read();
        for(int i=1;i<=n;i++)
         for(int j=1;j<=n;j++){
            f[i][j]=f[j][i]=read();
            if(j>=i+1) a[++top].a=i,a[top].b=j,a[top].len=f[i][j];
         }
        for(int i=1;i<=n+1;i++) fa[i]=i;
        for(int i=1;i<=n;i++) a[++top].a=i,a[top].b=n+1,a[top].len=w[i]; 
        sort(a+1,a+1+top,cmp);
        for(int i=1;i<=top;i++){
            if(find(a[i].a)!=find(a[i].b)){
                k++;unionn(a[i].a,a[i].b);
                ans+=a[i].len;
            }
            if(k==n) break;
        }
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    逆向入门之路1 关于逆向工程
    EC笔记:第三部分:14、在资源管理类中小心Copying行为
    vuex最简单、最详细的入门文档
    前端加密的几种常见方式
    NAS星云链 入门之从零开发第一个DAPP
    chrome 不支持12px以下字体为题的解决
    input checkbox 多选 验证
    你对javascript的原生操作或者工具了解多少呢?
    ionic2-键盘覆盖输入框和返回键问题解决方案
    ionic2 手风琴效果
  • 原文地址:https://www.cnblogs.com/stevensonson/p/7612200.html
Copyright © 2011-2022 走看看