【 UVALive - 5095】Transportation(费用流)

Description

There 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 ∗ x
2 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 ≤ N ≤ 100, 1 ≤ M ≤ 5000,
0 ≤ K ≤ 100). 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 ≤ ui
, vi ≤ N,
0 < ai ≤ 100, Ci ≤ 5)

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<=100)座城市,由m(m<=5000)条单向道路相连。你希望从城市1运送k(0<=k<=100)单位货物到城市n。这些道路并不安全,有很多强盗,所以你决定雇保镖来保护你。每条道路都有一个危险系数ai(0<ai<=100),如果你带着x个单位货物通过,需要给保镖aix^2元钱才能保证你的安全(这是合理的,因为带在身边的货物越多越不安全)。另外,每条路上还有一个容量限制Ci(Ci<=5),表示最多只能带Ci个单位的货物通过。注意,货物不能拆开,因此在通过每条边时,身上的货物数量必须是整数。

【分析】

  此题要拆边。(容量较小)

  对于一个费用系数为a,容量为5的边拆成5条容量为1,费用依次为1a,3a,5a,7a,9a的边。

  因为求的是最小费用流,如果这条弧的流量为1,走的肯定是1a;如果流量为2,走的肯定是1a,3a这两条,如果流量为3,走的肯定是1a,3a,5a……不难验证,不管流量是1~5之间的哪一个,相应流量选取的边的费用之和恰好就是未拆边是的相应费用。

  这样问题就转化成普通的最小费用最大流问题了。(当流量到达k即可break)

  费用流大概是这样做的:

  每次找费用最小的增广路走,走到走不完为止。所以最终ans是最大流前提下最小费用。

代码如下:

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<queue>
  7 using namespace std;
  8 #define Maxn 110
  9 #define Maxm 5100
 10 #define INF 0xfffffff
 11
 12 int n,m,k;
 13
 14 struct node
 15 {
 16     int x,y,f,c,o,next;
 17 }t[Maxm*10];int len;
 18 int first[Maxn];
 19 int flow[Maxn],dis[Maxn],pre[Maxn];
 20 bool inq[Maxn];
 21
 22 int mymin(int x,int y) {return x<y?x:y;}
 23
 24 void ins(int x,int y,int f,int c)
 25 {
 26     t[++len].x=x;t[len].y=y;t[len].f=f;t[len].c=c;
 27     t[len].next=first[x];first[x]=len;t[len].o=len+1;
 28     t[++len].x=y;t[len].y=x;t[len].f=0;t[len].c=-c;
 29     t[len].next=first[y];first[y]=len;t[len].o=len-1;
 30 }
 31
 32 queue<int > q;
 33 bool BFS(int f1,int f2)
 34 {
 35     while(!q.empty()) q.pop();
 36     memset(pre,-1,sizeof(pre));
 37     memset(inq,0,sizeof(inq));
 38     memset(dis,63,sizeof(dis));
 39     pre[f1]=0;flow[f1]=INF;inq[f1]=1;
 40     dis[f1]=0;q.push(f1);
 41     while(!q.empty())
 42     {
 43         int x=q.front(),y,i;
 44         for(i=first[x];i;i=t[i].next) if(t[i].f>0)
 45         {
 46             y=t[i].y;
 47             if(dis[y]>dis[x]+t[i].c)
 48             {
 49                 pre[y]=i;
 50                 dis[y]=dis[x]+t[i].c;
 51                 flow[y]=mymin(t[i].f,flow[x]);
 52                 if(!inq[y]) {q.push(y);inq[y]=1;}
 53             }
 54         }
 55         q.pop();inq[x]=0;
 56     }
 57     if(pre[f2]==-1) return 0;
 58     return flow[f2];
 59 }
 60
 61 void max_flow(int x,int y)
 62 {
 63     int a,sum=0,h=0;
 64     bool ok=0;
 65     while(a=BFS(x,y))
 66     {
 67         int now=y;sum+=a*dis[y];
 68         h+=a;
 69         while(now!=x)
 70         {
 71             t[pre[now]].f-=a;
 72             t[t[pre[now]].o].f+=a;
 73             now=t[pre[now]].x;
 74         }
 75         if(h>=k) break;
 76     }
 77     if(h<k) printf("-1\n");
 78     else printf("%d\n",sum);
 79 }
 80
 81 int main()
 82 {
 83     while(scanf("%d%d%d",&n,&m,&k)!=EOF)
 84     {
 85         len=0;
 86         memset(first,0,sizeof(first));
 87         for(int i=1;i<=m;i++)
 88         {
 89             int x,y,z,kk,now=0;
 90             scanf("%d%d%d%d",&x,&y,&z,&kk);
 91             for(int i=1;i<=kk;i++)
 92             {
 93                 ins(x,y,1,z*(i*i-now));
 94                 now+=i*i-now;
 95             }
 96         }
 97         max_flow(1,n);
 98     }
 99     return 0;
100 }

[LA5095]

2016-05-23 13:39:41

时间: 2024-11-05 20:42:57

【 UVALive - 5095】Transportation(费用流)的相关文章

UVALive - 5095 Transportation(拆边+费用流)

题目大意:有n个点,m条边,每条边的容量为ci,费用为ai* x^2(x为流量,ai为所给系数) 现在问能否将k个单位的货物从点1运输到点n,且费用最小 解题思路:拆边,将每条边拆成ci条边,每条边的费用分别为ai * 1, ai * 3, ai * 5-容量都为1,在容量相同的情况下,会选择费用少的流,这样流过的边累加起来的费用刚好为 ai * 流量^2 #include <cstdio> #include <cstring> #include <algorithm>

HDU 3667 Transportation(网络流之费用流)

题目地址:HDU 3667 这题的建图真是巧妙...为了保证流量正好达到k,需要让每一次增广到的流量都是1,这就需要把每一条边的流量都是1才行.但是每条边的流量并不是1,该怎么办呢.这个时候可以拆边,反正c最多只有5,拆成5条流量为1的边.但是这时候费用怎么办呢,毕竟平方的关系不能简单把每一条边加起来.这时候可以把拆的边的流量设为1,3,5,7,9.如果经过了3个流量,那就肯定会流1,3,5,费用为9,是3的平方,同理,其他的也是如此.然后按照给出的边建图跑一次费用流就可以了. 代码如下: #i

费用流 hdu3667 Transportation

传送门:点击打开链接 题意:n个节点m条有向边,每条有向边的容量是C,且费用是a*x^2,x是流量,问从1运送k流量到n的最小费用 一般做的费用流边的费用都是固定的,而这题并不是固定的. 但是,看到了C<=5,其实就是在提示可以拆边.. 假如C是3,我们就可以把一条边拆成3条边. 假如不拆,如果通过的流量是1,2,3,那么费用分别是a,4a,9a 如果拆成3条边,那么3条边的费用分别是a,3a,5a,容量都是1 这样就完美的解决了边的费用问题了~ #include<map> #inclu

【 UVALive - 2197】Paint the Roads(上下界费用流)

Description In a country there are n cities connected by m one way roads. You can paint any of these roads. To paint a road it costs d unit of money where d is the length of that road. Your task is to paint some of the roads so that the painted roads

【UVALive - 5131】Chips Challenge(上下界循环费用流)

Description A prominent microprocessor company has enlisted your help to lay out some interchangeable components(widgets) on some of their computer chips. Each chip’s design is an N × N square of slots. Oneslot can hold a single component, and you ar

zoj3231 Apple Transportation(最大流)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Apple Transportation Time Limit: 1 Second      Memory Limit: 32768 KB There's a big apple tree in the forest. In the tree there are N nodes (numbered from 0 to N - 1), and the nodes are conne

【网络流24题】No.19 负载平衡问题 (费用流)

[题意] G 公司有 n 个沿铁路运输线环形排列的仓库, 每个仓库存储的货物数量不等. 如何用最少搬运量可以使 n 个仓库的库存数量相同.搬运货物时,只能在相邻的仓库之间搬运. 输入文件示例input.txt517 9 14 16 4 输出文件示例output.txt11 [分析] 其实我觉得这题可以贪心啊..n^2贪心??.没细想.. 打的是费用流.. 大概这样建图: 懒得写了..凌乱之美.. 求满流费用.. 1 #include<cstdio> 2 #include<cstdlib&

POJ 3422 kaka&#39;s matrix trvals(费用流)

#include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <set> #include <map> #include <cma

hdu 2448 Mining Station on the Sea【网络费用流】

Mining Station on the Sea Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2371    Accepted Submission(s): 732 Problem Description The ocean is a treasure house of resources and the development