码迷,mamicode.com
首页 > 其他好文 > 详细

取水问题

时间:2019-03-14 10:32:22      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:去掉   struct   else   cin   class   other   space   div   最小   

http://acm.zjnu.edu.cn/CLanguage/showproblem?problem_id=1213

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最少要花多少钱才能够让他的所有牧场都有水源。

 

技术图片

 

 解法一:

  先每个地方都修一个水井。

  将所有的无向边从小到大排序,按照最小生成树的思路,试着将边加入。比如有边edge[i][j]将点i和点j连通,如果修路的费用edge[i][j]小于修水井 i 的费用或者小于修水井 j 的费用,则可以加入这条边,然后可以去掉水井 i 和水井 j 中费用最大的那个。

 1 #include<iostream>
 2 #include<vector>
 3 #include<stdio.h> 
 4 #include<stdlib.h>
 5 #include<set>
 6 #include<string>
 7 #include<algorithm>
 8 using namespace std;
 9 
10 int ans = 0;
11 
12 int father[305];
13 int cost1[305];
14 int cost2[305][305]; 
15 int n;
16 struct road{
17     int i, j, cost;
18     road(int a, int b, int c){
19         i = a, j = b, cost = c;
20     }
21     bool operator<(const struct road &other)const{
22         return cost < other.cost;
23     }
24 };
25 int find(int i){
26     if(father[i] != i) father[i] = find(father[i]);
27     return father[i];
28 }
29 void union_(int i, int j){
30     int fi = find(i), fj = find(j);
31     if(fi == fj) return ;
32     if(cost2[i][j] > max(cost1[fi], cost1[fj])) return ;
33     if(cost1[fi] < cost1[fj]){
34         father[fj] = fi, ans = ans - cost1[fj] + cost2[i][j];
35     }else{
36         father[fi] = fj, ans = ans - cost1[fi] + cost2[i][j];
37     }
38 } 
39 vector<struct road> roads;
40 int main(){
41     cin>>n;
42     for(int i = 0; i < n; i++){
43         father[i] = i;
44         cin>>cost1[i];
45         ans += cost1[i];
46     }
47     for(int i = 0; i < n; i++){
48         for(int j = 0; j < n; j++){
49             cin>>cost2[i][j];
50         }
51     }
52     for(int i = 0; i < n; i++){
53         for(int j = i + 1; j < n; j++){
54             struct road temp(i, j, cost2[i][j]);
55             roads.push_back(temp);
56         }
57     }
58     sort(roads.begin(), roads.end());
59     for(int i = 0; i < roads.size(); i++){
60         union_(roads[i].i, roads[i].j);
61     }
62     cout<<ans;
63     return 0;
64 } 

 

解法二:

  设立一个虚拟点n,这个点免费提供水源。

  在点 i 修水井的钱,可以看做是从 i 到 n修路的钱。

  那么这样的话,可以看做将点0到点n构造一棵最小生成树。

 1 #include<iostream>
 2 #include<vector>
 3 #include<stdio.h> 
 4 #include<stdlib.h>
 5 #include<set>
 6 #include<string>
 7 #include<algorithm>
 8 using namespace std;
 9 
10 int ans = 0;
11 
12 int father[305];
13 int cost1[305];
14 int cost2[305][305]; 
15 int n;
16 struct road{
17     int i, j, cost;
18     road(int a, int b, int c){
19         i = a, j = b, cost = c;
20     }
21     bool operator<(const struct road &other)const{
22         return cost < other.cost;
23     }
24 };
25 int find(int i){
26     if(father[i] != i) father[i] = find(father[i]);
27     return father[i];
28 }
29 void union_(int i, int j, int cost){
30     int fi = find(i), fj = find(j);
31     if(fi == fj) return ;
32     father[fi] = fj, ans = ans + cost;
33 } 
34 vector<struct road> roads;
35 int main(){
36     cin>>n;
37     father[n] = n;
38     for(int i = 0; i < n; i++){
39         father[i] = i;
40         cin>>cost1[i];
41         struct road temp(i, n, cost1[i]);
42         roads.push_back(temp);
43     }
44     for(int i = 0; i < n; i++){
45         for(int j = 0; j < n; j++){
46             cin>>cost2[i][j];
47         }
48     }
49     for(int i = 0; i < n; i++){
50         for(int j = i + 1; j < n; j++){
51             struct road temp(i, j, cost2[i][j]);
52             roads.push_back(temp);
53         }
54     }
55     sort(roads.begin(), roads.end());
56     for(int i = 0; i < roads.size(); i++){
57         union_(roads[i].i, roads[i].j, roads[i].cost);
58     }
59     cout<<ans;
60     return 0;
61 } 

 

取水问题

标签:去掉   struct   else   cin   class   other   space   div   最小   

原文地址:https://www.cnblogs.com/liqiniuniu/p/10528532.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!