zoj 3231(上下界费用流)

题意:树上每个节点上有若干苹果,边上带权,问你最小费用使得书上的苹果方差最小。

思路:上下费用流问题,参考http://blog.csdn.net/qq564690377/article/details/8870587

代码如下:

  1 /**************************************************
2 * Author : xiaohao Z
3 * Blog : http://www.cnblogs.com/shu-xiaohao/
4 * Last modified : 2014-05-13 12:02
5 * Filename : zoj_3231_2.cpp
6 * Description :
7 * ************************************************/
8
9 #include <iostream>
10 #include <cstdio>
11 #include <cstring>
12 #include <cstdlib>
13 #include <cmath>
14 #include <algorithm>
15 #include <queue>
16 #include <stack>
17 #include <vector>
18 #include <set>
19 #include <map>
20 #define MP(a, b) make_pair(a, b)
21 #define PB(a) push_back(a)
22
23 using namespace std;
24 typedef long long ll;
25 typedef pair<int, int> pii;
26 typedef pair<unsigned int,unsigned int> puu;
27 typedef pair<int, double> pid;
28 typedef pair<ll, int> pli;
29 typedef pair<int, ll> pil;
30
31 const int INF = 0x3f3f3f3f;
32 const double eps = 1E-6;
33 const int MAXN = 10000;
34 const int MAXM = 100000;
35 struct Edge{int to,next,cap,flow,cost;}edge[MAXM];
36 int head[MAXN],tol;
37 int pre[MAXN],dis[MAXN];
38 bool vis[MAXN];
39 int N;//节点总个数,节点编号从0~N-1
40
41 void init(int n)
42 {
43 N = n;
44 tol = 0;
45 memset(head,-1,sizeof(head));
46 }
47
48 void addedge(int u,int v,int cap,int cost)
49 {
50 edge[tol].to = v;
51 edge[tol].cap = cap;
52 edge[tol].cost = cost;
53 edge[tol].flow = 0;
54 edge[tol].next = head[u];
55 head[u] = tol++;
56 edge[tol].to = u;
57 edge[tol].cap = 0;
58 edge[tol].cost = -cost;
59 edge[tol].flow = 0;
60 edge[tol].next = head[v];
61 head[v] = tol++;
62 }
63 bool spfa(int s,int t)
64 {
65 queue<int>q;
66 for(int i = 0; i < N; i++)
67 {
68 dis[i] = INF;
69 vis[i] = false;
70 pre[i] = -1;
71 }
72 dis[s] = 0;
73 vis[s] = true;
74 q.push(s);
75 while(!q.empty())
76 {
77 int u = q.front();
78 q.pop();
79 vis[u] = false;
80 for(int i = head[u]; i != -1; i = edge[i].next)
81 {
82 int v = edge[i].to;
83 if(edge[i].cap > edge[i].flow &&
84 dis[v] > dis[u] + edge[i].cost )
85 {
86 dis[v] = dis[u] + edge[i].cost;
87 pre[v] = i;
88 if(!vis[v])
89 {
90 vis[v] = true;
91 q.push(v);
92 }
93 }
94 }
95 }
96 if(pre[t] == -1)return false;
97 else return true;
98 }
99 //返回的是最大流,cost存的是最小费用
100 int minCostMaxflow(int s,int t,int &cost)
101 {
102 int flow = 0;
103 cost = 0;
104 while(spfa(s,t))
105 {
106 int Min = INF;
107 for(int i = pre[t]; i != -1; i = pre[edge[i^1].to])
108 {
109 if(Min > edge[i].cap - edge[i].flow)
110 Min = edge[i].cap - edge[i].flow;
111 }
112 for(int i = pre[t]; i != -1; i = pre[edge[i^1].to])
113 {
114 edge[i].flow += Min;
115 edge[i^1].flow -= Min;
116 cost += edge[i].cost * Min;
117 }
118 flow += Min;
119 }
120 return flow;
121 }
122
123 int main()
124 {
125 // freopen("in.txt", "r", stdin);
126 int a, b, n, vex[101], val, sum;
127 while(scanf("%d", &n)!=EOF){
128 sum = 0;
129 for(int i=1; i<=n; i++){
130 scanf("%d", &vex[i]);
131 sum += vex[i];
132 }
133 init(n+3);
134 for(int i=1; i<n; i++){
135 scanf("%d%d%d", &a, &b, &val);
136 a++, b++;
137 addedge(a, b, INF, val);
138 addedge(b, a, INF, val);
139 }
140 for(int i=1; i<=n; i++){
141 addedge(0, i, vex[i], 0);
142 addedge(i, n+1, sum/n, 0);
143 addedge(i, n+2, 1, 0);
144 }
145 addedge(n+2, n+1, sum%n, 0);
146 int ans;
147 minCostMaxflow(0, n+1, ans);
148 printf("%d\n", ans);
149 }
150 return 0;
151 }

zoj 3231(上下界费用流),布布扣,bubuko.com

时间: 2024-10-21 10:50:12

zoj 3231(上下界费用流)的相关文章

【bzoj1927】[Sdoi2010]星际竞速 有上下界费用流

原文地址:http://www.cnblogs.com/GXZlegend/p/6832464.html 题目描述 10年一度的银河系赛车大赛又要开始了.作为全银河最盛大的活动之一,夺得这个项目的冠军无疑是很多人的梦想,来自杰森座α星的悠悠也是其中之一.赛车大赛的赛场由N颗行星和M条双向星际航路构成,其中每颗行星都有一个不同的引力值.大赛要求车手们从一颗与这N颗行星之间没有任何航路的天体出发,访问这N颗行星每颗恰好一次,首先完成这一目标的人获得胜利.由于赛制非常开放,很多人驾驶着千奇百怪的自制赛

【bzoj4108】[Wf2015]Catering 有上下界费用流

原文地址:http://www.cnblogs.com/GXZlegend/p/6832537.html 题目描述 有一家装备出租公司收到了按照时间顺序排列的n个请求. 这家公司有k个搬运工.每个搬运工可以搬着一套装备按时间顺序去满足一些请求.一个搬运工从第i个请求的位置把东西搬到第j个请求的位置需要一些费用.公司的编号是1,请求的编号是2到n+1.所有搬运工必需从公司出发. 求满足所有请求所需的最小搬运费用. 输入 有可能有多组数据.(实际上没有) 第一行两个正整数n,k. 接下来n行,第i行

【bzoj2324】[ZJOI2011]营救皮卡丘 最短路-Floyd+有上下界费用流

原文地址:http://www.cnblogs.com/GXZlegend/p/6832504.html 题目描述 皮卡丘被火箭队用邪恶的计谋抢走了!这三个坏家伙还给小智留下了赤果果的挑衅!为了皮卡丘,也为了正义,小智和他的朋友们义不容辞的踏上了营救皮卡丘的道路. 火箭队一共有N个据点,据点之间存在M条双向道路.据点分别从1到N标号.小智一行K人从真新镇出发,营救被困在N号据点的皮卡丘.为了方便起见,我们将真新镇视为0号据点,一开始K个人都在0号点. 由于火箭队的重重布防,要想摧毁K号据点,必须

hdu 4862 Jump 上下界费用流

对于每个点拆点成为两个点a,b,连接a到b的上界为1,下界为1的边,保证用过一次且仅一次. 然后若点u可到达点v,则连接即可.建成了一个上下界网络,将下界拆出去,求最大费用最大流就好. #include <stdio.h> #include <iostream> #include <string.h> using namespace std; const int N=800; const int MAXE=200000; const int inf=1<<3

Acdream 1171 Matrix sum 上下界费用流

题目链接:点击打开链接 Matrix sum Time Limit: 8000/4000MS (Java/Others)Memory Limit: 128000/64000KB (Java/Others) SubmitStatisticNext Problem Problem Description sweet和zero在玩矩阵游戏,sweet画了一个N * M的矩阵,矩阵的每个格子有一个整数.zero给出N个数Ki,和M个数Kj,zero要求sweet选出一些数,满足从第 i 行至少选出了Ki

【bzoj2055】80人环游世界 有上下界费用流

原文地址:http://www.cnblogs.com/GXZlegend 题目描述 想必大家都看过成龙大哥的<80天环游世界>,里面的紧张刺激的打斗场面一定给你留下了深刻的印象.现在就有这么 一个80人的团伙,也想来一次环游世界. 他们打算兵分多路,游遍每一个国家. 因为他们主要分布在东方,所以他们只朝西方进军.设从东方到西方的每一个国家的编号依次为1...N.假若第i个人的游历路线为P1.P2......Pk(0≤k≤N),则P1<P2<......<Pk. 众所周知,中

[上下界费用流]JZOJ 3302 供电网络

Description 阿狸和桃子居住的世界里, 只有一个国家, 这个国家有很多城市, 每个城市直接由中央政府管辖.电力是这个国家的唯一能源, 但是每个城市的发电能力都不一样, 于是就产生了某些城市电力不足, 而某些城市却电力过剩的情况.阿狸作为国家的首席工程师, 阿狸的一项重要工作就是均衡整个国家的电力, 使得每个城市的电力都恰好没有剩余或不足.好在一些城市之间有电线可以输送电力, 这些电线都有自己的输送上限和下限, 并且输送电力的同时会产生大量的热.每条电线i 发出的热量一定是关于输送电量的

P4043 [AHOI2014/JSOI2014]支线剧情 上下界费用流

题意: 有个人每次可以从1出发(可以无限次)  走有向边  耗费的时间为有向边的长度   问最少耗费的时间遍历所有的边至少一次 有点像滑雪那题  不过那题求得是最少的次数 这题很显然可以转化为上下界费用流  只要设置边的容量为1-inf 即可 注意: 上下界费用流的答案为: 答案即为(求出的费用+原图中边的下界*边的费用) 答案即为(求出的费用+原图中边的下界*边的费用) 答案即为(求出的费用+原图中边的下界*边的费用) 答案即为(求出的费用+原图中边的下界*边的费用) #include<bit

bzoj 1061 志愿者招募 有上下界费用流做法

把每一天看作一个点,每一天的志愿者数目就是流量限制,从i到i+1连边,上下界就是(A[i],+inf). 对于每一类志愿者,从T[i]+1到S[i]连边,费用为招募一个志愿者的费用,流量为inf.这样每多1的流量,就多了一个从S[i]到T[i]+1的循环流. 求一遍无源汇的最小费用可行流就可以了. 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring>