• BZOJ 1601 [Usaco2008 Oct]灌水:最小生成树


    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1601

    题意:

      Farmer John已经决定把水灌到他的n(1<=n<=300)块农田,农田被数字1到n标记。

      把一块土地进行灌水有两种方法,从其他农田饮水,或者这块土地建造水库。

      建造一个水库需要花费wi(1<=wi<=100000),连接两块土地需要花费P[i][j](1 <= p[i][j] <= 100000, p[i][j]=p[j][i], p[i][i]=0)。

      计算Farmer John所需的最少代价。

    题解:

      农田标号1到n,建立超级源点为0号点。

      从超级源点向每个农田连一条长度为w[i]的边。然后n个农田之间再互相连接,边长为p[i][j]。

      然后求最小生成树就好。

    AC Code:

      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <string.h>
      4 #include <algorithm>
      5 #include <vector>
      6 #define MAX_N 305
      7 
      8 using namespace std;
      9 
     10 struct Edge
     11 {
     12     int sour;
     13     int dest;
     14     int len;
     15     Edge(int _sour,int _dest,int _len)
     16     {
     17         sour=_sour;
     18         dest=_dest;
     19         len=_len;
     20     }
     21     Edge(){}
     22     friend bool operator < (const Edge &a,const Edge &b)
     23     {
     24         return a.len<b.len;
     25     }
     26 };
     27 
     28 int n;
     29 int ans;
     30 int par[MAX_N];
     31 vector<Edge> edge;
     32 
     33 void init_union_find()
     34 {
     35     for(int i=0;i<=n;i++)
     36     {
     37         par[i]=i;
     38     }
     39 }
     40 
     41 int find(int x)
     42 {
     43     return par[x]==x?x:par[x]=find(par[x]);
     44 }
     45 
     46 void unite(int x,int y)
     47 {
     48     int px=find(x);
     49     int py=find(y);
     50     if(px==py) return;
     51     par[px]=py;
     52 }
     53 
     54 bool same(int x,int y)
     55 {
     56     return find(x)==find(y);
     57 }
     58 
     59 int kruskal()
     60 {
     61     init_union_find();
     62     sort(edge.begin(),edge.end());
     63     int cnt=0;
     64     int res=0;
     65     for(int i=0;i<edge.size();i++)
     66     {
     67         Edge temp=edge[i];
     68         if(!same(temp.sour,temp.dest))
     69         {
     70             cnt++;
     71             res+=temp.len;
     72             unite(temp.sour,temp.dest);
     73         }
     74     }
     75     return cnt==n?res:-1;
     76 }
     77 
     78 void read()
     79 {
     80     cin>>n;
     81     int a;
     82     for(int i=1;i<=n;i++)
     83     {
     84         cin>>a;
     85         edge.push_back(Edge(0,i,a));
     86     }
     87     for(int i=1;i<=n;i++)
     88     {
     89         for(int j=1;j<=n;j++)
     90         {
     91             cin>>a;
     92             if(i<j) edge.push_back(Edge(i,j,a));
     93         }
     94     }
     95 }
     96 
     97 void solve()
     98 {
     99     ans=kruskal();
    100 }
    101 
    102 void print()
    103 {
    104     cout<<ans<<endl;
    105 }
    106 
    107 int main()
    108 {
    109     read();
    110     solve();
    111     print();
    112 }
  • 相关阅读:
    JNI在C 和 C++ 函数实现的不同
    JNI输出log信息
    Android.mk相关知识
    Android项目编译和使用C语言动态库(so库)
    Jmeter之JDBC请求(四)
    Jmeter之Badboy录制脚本及简化脚本http请求(三)
    Jmeter之录制脚本(二)
    Android自动化压力测试之Monkey Test 异常解读(五)
    Android自动化压力测试之Monkey Test Android常见的错误类型及黑白名单的使用方法(四)
    Android自动化压力测试之Monkey Test (三)
  • 原文地址:https://www.cnblogs.com/Leohh/p/7623401.html
Copyright © 2020-2023  润新知