zoukankan      html  css  js  c++  java
  • bzoj1601 [Usaco2008 Oct]灌水

    1601: [Usaco2008 Oct]灌水

    Time Limit: 5 Sec  Memory Limit: 162 MB
    Submit: 2147  Solved: 1409
    [Submit][Status][Discuss]

    Description

    Farmer John已经决定把水灌到他的n(1<=n<=300)块农田,农田被数字1到n标记。把一块土地进行灌水有两种方法,从其他农田饮水,或者这块土地建造水库。 建造一个水库需要花费wi(1<=wi<=100000),连接两块土地需要花费Pij(1<=pij<=100000,pij=pji,pii=0). 计算Farmer John所需的最少代价。

    Input

    *第一行:一个数n

    *第二行到第n+1行:第i+1行含有一个数wi

    *第n+2行到第2n+1行:第n+1+i行有n个被空格分开的数,第j个数代表pij。

    Output

    *第一行:一个单独的数代表最小代价.

    Sample Input

    4
    5
    4
    4
    3
    0 2 2 2
    2 0 3 3
    2 3 0 4
    2 3 4 0

    Sample Output

    9


    输出详解:

    Farmer John在第四块土地上建立水库,然后把其他的都连向那一个,这样就要花费3+2+2+2=9

    HINT

     

    Source

    资格赛

    分析:比较经典的转换.如果不考虑点权,那么就是最小生成树了.考虑点权的话方法还是不变,只是可能会形成森林,要使得所有的树都指向一个点,那么建一个源点就好了.这个点连向其它的点,边权为所连的点的点权,做一次最小生成树.

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    int n, ans, w[310], fa[310], a[310][310], cnt;
    bool vis[310];
    
    struct node
    {
        int x, y, z;
    }e[1010010];
    
    bool cmp(node a, node b)
    {
        return a.z < b.z;
    }
    
    int find(int x)
    {
        if (x == fa[x])
            return x;
        return fa[x] = find(fa[x]);
    }
    
    int main()
    {
        scanf("%d", &n);
        for (int i = 1; i <= n + 1; i++)
            fa[i] = i;
        for (int i = 1; i <= n; i++)
            scanf("%d", &w[i]);
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
            {
                scanf("%d", &a[i][j]);
                e[++cnt].x = i;
                e[cnt].y = j;
                e[cnt].z = a[i][j];
            }
        for (int i = 1; i <= n; i++)
        {
            e[++cnt].x = i;
            e[cnt].y = n + 1;
            e[cnt].z = w[i];
        }
        sort(e + 1, e + 1 + cnt, cmp);
        for (int i = 1; i <= cnt; i++)
        {
            int fx = find(e[i].x), fy = find(e[i].y);
            if (fx != fy)
            {
                ans += e[i].z;
                fa[fx] = fy;
            }
        }
    
        printf("%d
    ", ans);
    
        return 0;
    }
  • 相关阅读:
    Hello China最新开发进展
    虚拟软驱影像文件制作程序下载路径:http://download.csdn.net/source/738137
    Swing透明和变换
    利用Java存储过程简化数据库操作
    Hello China V1.5 源码下载地址
    防止程序重复执行的单元
    判断文件大小的函数
    TMainMenu 隐藏与显示菜单
    最简单的Delphi程序(控制台)
    测试代码
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7853159.html
Copyright © 2011-2022 走看看