uva 1486 Transportation (费用流+拆边)
2015-08-09 16:55
260 查看
uva 1486 Transportation
DescriptionThere are N cities, and M directed roads connecting them. Now you want to transport K units of goods from city 1 to city N. There are many robbers on the road, so you must be very careful. The more goods you carry, the more dangerous it is. To be more specific, for each road i, there is a coefficient ai. If you want to carry x units of goods along this road, you should pay ai*x2 dollars to hire guards to protect your goods. And what’s worse, for each road i, there is an upper bound Ci, which means that you cannot transport more than Ci units of goods along this road. Please note you can only carry integral unit of goods along each road.
You should find out the minimum cost to transport all the goods safely.
Input
There are several test cases. The first line of each case contains three integers, N, M and K. (1≤ \leN≤ \le100, 1≤ \leM≤ \le5000, 0≤ \leK≤ \le100). Then M lines followed, each contains four integers (ui, vi, ai, Ci), indicating there is a directed road from city ui to vi, whose coefficient is ai and upper bound is Ci. (1≤ \leui, vi≤ \leN, 0 < ai≤ \le100, Ci≤ \le5)
Output
Output one line for each test case, indicating the minimum cost. If it is impossible to transport all the K units of goods, output `-1’.
Sample Input
2 1 2
1 2 1 2
2 1 2
1 2 1 1
2 2 2
1 2 1 2
1 2 2 2
Sample Output
4
-1
3
题目大意:某国有n(n<=100n<=100)座城市,由m(m<=5000m<=5000)条单向道路相连。你希望从城市1运送k(k<=100k<=100)单位货物到城市n,这些道路并不安全,有很多强盗,所以你需要雇佣镖师来做护卫。每条道路都有一个危险系数ai(ai<=100ai<=100),如果你带着x个单位的货物通过,需要给镖师ai∗x2ai*x^2的佣金,镖师才会保证你的安全。每条道路都有一个限制,最多能运送Ci(Ci<=5Ci<=5)的货物。现在问,在能完成运送x个单位的货物到n号城市的情况下最小的花费,如果送不到,则输出-1。
解题思路:如果不进行拆边的话,每条道路的费用是动态变化的,所以我们要进行拆边,使得每条道路的费用固定。假如一条边的危险系数是a,最多能运送的货物为C,那么这条边就可以C条边每条边的费用为a∗(i2−(i−1)2)a*(i^2 - (i - 1)^2),i从1到C,容量为1。这样拆出来的边总费用为a∗C2a*C^2,总容量为C。拆完边,建完图,跑一发最小费。
[code]#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <cstdlib> #include <queue> using namespace std; const int INF = 0x3f3f3f3f; const int N = 200; const int M = 150000; typedef long long ll; int n, m, k, s, t; int pre , inq ; ll a , d ; struct Edge{ int from, to; ll cap, flow; ll cos; }; vector<Edge> edges; vector<int> G[M]; void init() { for (int i = 0; i < M; i++) G[i].clear(); edges.clear(); } void addEdge(int from, int to, ll cap, ll flow, ll cos) { edges.push_back((Edge){from, to, cap, 0, cos}); edges.push_back((Edge){to, from, 0, 0, -cos}); int m = edges.size(); G[from].push_back(m - 2); G[to].push_back(m - 1); } int BF(int s, int t, ll& flow, ll& cost) { queue<int> Q; memset(inq, 0, sizeof(inq)); memset(a, 0, sizeof(a)); memset(pre, 0, sizeof(pre)); for (int i = 0; i < N; i++) d[i] = INF; d[s] = 0; a[s] = INF; inq[s] = 1; int flag = 1; pre[s] = 0; Q.push(s); while (!Q.empty()) { int u = Q.front(); Q.pop(); inq[u] = 0; for (int i = 0; i < G[u].size(); i++) { Edge &e = edges[G[u][i]]; if (e.cap > e.flow && d[e.to] > d[u] + e.cos) { d[e.to] = d[u] + e.cos; a[e.to] = min(a[u], e.cap - e.flow); pre[e.to] = G[u][i]; if (!inq[e.to]) { inq[e.to] = 1; Q.push(e.to); } } } flag = 0; } if (d[t] == INF) return 0; flow += a[t]; cost += (ll)d[t] * (ll)a[t]; for (int u = t; u != s; u = edges[pre[u]].from) { edges[pre[u]].flow += a[t]; edges[pre[u]^1].flow -= a[t]; } return 1; } int MCMF(int s, int t, ll& cost) { ll flow = 0; cost = 0; while (BF(s, t, flow, cost)); return flow; } void input() { int u, v; ll a; ll c; for (int i = 0; i < m; i++) { scanf("%d %d %lld %lld", &u, &v, &a, &c); for (int i = 1; i <= c; i++) { addEdge(u, v, 1, 0, a * (i * i - (i - 1) * (i - 1))); } } addEdge(0, 1, k, 0, 0); s = 0, t = n; } int main() { while (scanf("%d %d %d", &n, &m, &k) == 3) { init(); input(); ll cost; if (MCMF(s, t, cost) != k) printf("-1\n"); else printf("%lld\n", cost); } return 0; }
相关文章推荐
- 《围住神经猫》的逃跑路径算法
- 轻量级文本编辑器,Notepad最佳替代品:Notepad++
- Android Format的使用
- Linux下用php调用C接口(扩展)的资料
- 管道,信号量,共享内存,socket的实际使用场景和NSPipe管道的使用
- jQuery中的Ajax
- (算法:二分查找)在排序数组中,找出给定数字出现的次数
- 2015公务员工资改革消息:广州人社局长称基层公务员工资肯定会增不少
- Java的date和以datetime为字段的数据库的处理办法
- hdu-2114-Calculate S(n)
- 为什么你宁愿每周工作90小时,也不做任何改变?(转载)
- 使用代码为textview设置drawableLeft
- 大苏格兰2015年中学等级考试的一道初等数学题
- Java查看List扩容后的容量
- 10.1——pair,map,set,multimap,multiset
- OpenGl编程指南例2.4大白话分析
- MVC简单实现查询列表
- Leetcode52 N-Queens II
- MongoDB查询
- sp_send_dbmail参数设置