zoukankan      html  css  js  c++  java
  • 取水

      

    题目描述

    Famer John希望把水源引入他的N (1 <= N <= 300) 个牧场,牧场的编号是1~N。他将水源引入某个牧场的方法有两个,一个是在牧场中打一口井,另一个是将这个牧场与另一个已经有水源的牧场用一根管道相连。在牧场i中打井的费用是W_i (1 <= W_i <= 100000)。把牧场i和j用一根管道相连的费用是P_ij (1 <= P_ij <= 100000, P_ij = P_ji, P_ii = 0)。请你求出Farmer John最少要花多少钱才能够让他的所有牧场都有水源。

    输入

    * 第1行: 一个正整数N. 
    * 第2~N+1行: 第i+1行包含一个正整数W_i. 
    * 第N+2~2N+1行: 第N+1+i行包含N个用空格分隔的正整数,第j个数表示P_ij. 

    输出

    最少要花多少钱才能够让他的所有牧场都有水源。

    样例输入

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

    样例输出

    9

    提示

    输入数据解释 总共有四个牧场.在1号牧场打一口井需要5的费用,在2或者3号牧场打井需要4的费用,在4号牧场打井需要3的费用.在不同的牧场间建立管道需要2,3或4的费用.
    输出数据解释 Farmer John需要在4号牧场打一口井,然后把所有牧场都用管道连到1号牧场上,总共的花费是3+2+2+2=9.
    对于30%的数据N<=10 
    对于60%的数据N<=100 
    对于100%的数据N<=300 

    这一道题目题目大意就是给你N个点的无向完全图,然后,每一个点都要有水源。这里我们可以设置一个超级源0,我们可以想象打井就相当于和这个0点连一条边。虽然小Z推荐了Prim做法,因为这是一个完全图。但是,由于我比较懒,所以我依然用了Kruskal。。。

     1 #include <cmath>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <iostream>
     5 #include <algorithm>
     6 
     7 using namespace std;
     8 
     9 struct node
    10 {
    11     int u,v,cost;    
    12 };
    13 
    14 
    15 node a[100005];
    16 int f[100005];
    17 int N;
    18 int Len=0;
    19 
    20 bool cmp(node i,node j)
    21 {
    22     return i.cost < j.cost;
    23 }
    24 
    25 int find(int X)
    26 {
    27     if (f[X] != X) f[X]=find(f[X]);
    28     return f[X];
    29 }
    30 
    31 int main()
    32 {
    33     scanf("%d",&N);
    34     for (int i=1; i<=N; i++)
    35     {
    36         int X;
    37         scanf("%d",&X);
    38         a[++Len].u=0; a[Len].v=i; a[Len].cost=X;
    39         f[i]=i;
    40     }
    41     for (int i=1; i<=N; i++)
    42     {
    43         for (int j=1; j<=N; j++)
    44         {
    45             int X;
    46             scanf("%d",&X);
    47             if (i == j) continue;
    48             a[++Len].u=i; a[Len].v=j; a[Len].cost=X;
    49         }
    50     }
    51     int ans=0; int total=0;
    52     sort(a+1,a+Len+1,cmp);
    53     for (int i=1; i<=Len; i++)
    54     {
    55         int fx=find(a[i].u);
    56         int fy=find(a[i].v);
    57         if (fx > fy) swap(fx,fy);
    58         if (fx == fy) continue;
    59         if (fx != fy)
    60         {
    61             f[fy]=fx;
    62             ans+=a[i].cost;
    63             total++;
    64             if (total == N) break;
    65         }
    66     }
    67     printf("%d\n",ans);
    68 }
    Show My Ugly Code
  • 相关阅读:
    Qt 最简单的多线程方法QtConcurrent::run()
    Qt 串口收发数据
    QString使用split按照某字符进行分解
    QT新建QWidget提示框(包含设置QLabel文字大小和居中)
    Mac电脑Docker拉取Mysql报错 no matching manifest for linux/arm64/v8 in the manifest list entries
    Goframe因为axios的header导致的一个BUG解析
    PHP版本如何写出让人很难理解的代码,显得自己很有水平
    vue通用配置异步加载同时保证同步
    GO性能分析pprof
    GO runtime的用法
  • 原文地址:https://www.cnblogs.com/TUncleWangT/p/7064931.html
Copyright © 2011-2022 走看看