HDU 3667 最小费用最大流+拆边
来源:互联网 发布:成都医疗大数据公司 编辑:程序博客网 时间:2024/05/18 01:13
Transportation
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1599 Accepted Submission(s): 623
Problem 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 * 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 <= 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
题目大意:要求从点1运输K件货物到点N,每对顶点间的费用为 a*x*x,其中x为该段路的流量,a为一个费用参数。求最小费用。
思路:题目明显是最小费用最大流问题,考虑到每段路的最大流量小于5,则可以将边拆开。比如s->e之间可以运输3件货物,那么将s->e拆成3条边(每条边视作不同的路),流量为1(只能走一次),假如单位费用为a,则该三条边的费用分别为a*1,a*3,a*5,假如该三条路都走了,就相当于直接从s到e运输三件货物,费用为a*3*3 = a*(1 + 3 + 5); 因为在该条路上运输2件货物这个问题上是包含了运输1件货物的,所以如果走了运输量为2件的这条路,潜意思就是运输量为1件的路也走了,所以当添加s->e且数量为2件的时候,费用应该为a*2*2-a*1*1 = 3*a,也就是 a*(n*n)-a*((n-1)*(n-1)) = 2*n - 1.
最后构造一个源点连接到起始点1上,费用为0,流量为K。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <queue> 6 #define INF 0xfffffff 7 #define MAX 105 8 9 using namespace std; 10 11 struct node 12 { 13 int to,val,cost,re,next; 14 }; 15 16 node edge[MAX*1005]; 17 int head[MAX]; 18 int idx; 19 20 int N,M,K; 21 22 int source,sink,pt; 23 int pre[MAX],pos[MAX]; 24 int dis[MAX]; 25 bool inQueue[MAX]; 26 27 void addNode(int from,int to,int val,int cost) 28 { 29 edge[idx].to = to; 30 edge[idx].val = val; 31 edge[idx].cost = cost; 32 edge[idx].re = idx + 1; 33 edge[idx].next = head[from]; 34 head[from] = idx ++; 35 edge[idx].to = from; 36 edge[idx].val = 0; 37 edge[idx].cost = - cost; 38 edge[idx].re = idx - 1; 39 edge[idx].next = head[to]; 40 head[to] = idx ++; 41 } 42 43 bool spfa() 44 { 45 queue <int> Q; 46 for(int i=0; i<=pt; i++) 47 { 48 dis[i] = INF; 49 inQueue[i] = false; 50 } 51 dis[source] = 0; 52 pre[source] = source; 53 Q.push(source); 54 inQueue[source] = true; 55 while(!Q.empty()) 56 { 57 int cur = Q.front(); 58 Q.pop(); 59 inQueue[cur] = false; 60 for(int i=head[cur]; i!=-1; i=edge[i].next) 61 { 62 int to = edge[i].to; 63 if(edge[i].val > 0 && dis[to] > dis[cur] + edge[i].cost) 64 { 65 dis[to] = dis[cur] + edge[i].cost; 66 pre[to] = cur; 67 pos[to] = i; 68 if(!inQueue[to]) 69 { 70 Q.push(to); 71 inQueue[to] = true; 72 } 73 } 74 } 75 } 76 if(pre[sink]!=-1 && dis[sink] < INF) 77 return true; 78 return false; 79 } 80 81 int end() 82 { 83 int flow = 0,cost = 0; 84 while(spfa()) 85 { 86 int Min = INF; 87 for(int i=sink; i!=source; i=pre[i]) 88 Min = min(Min,edge[pos[i]].val); 89 flow += Min; 90 cost += Min*dis[sink]; 91 for(int i=sink; i!=source; i=pre[i]) 92 { 93 edge[pos[i]].val -= Min; 94 edge[pos[i]^1].val += Min; 95 } 96 } 97 if(flow < K) 98 return -1; 99 return cost;100 }101 102 int main()103 {104 while(~scanf("%d%d%d",&N,&M,&K))105 {106 idx = 0;107 memset(head,-1,sizeof(head));108 for(int i=1; i<=M; i++)109 {110 int s,e,v,c;111 scanf("%d%d%d%d",&s,&e,&v,&c);112 for(int j=1; j<=c; j++)113 addNode(s,e,1,v*(2*j-1));114 }115 source = 0;116 sink = N;117 pt = N + 2;118 addNode(source,1,K,0);119 int ans = end();120 printf("%d\n",ans);121 }122 return 0;123 }
- HDU 3667 最小费用最大流+拆边
- HDU 3667 Transportation (最小费用最大流)
- 最小费用最大流 hdu 3667
- HDU 3667 Transportation(最小费用最大流)
- HDU 3667 Transportation(最小费用最大流)
- hdu 3667(拆边+最小费用最大流)
- hdu 3667 Transportation(最小费用最大流 拆边)
- HDU 3667Transportation(最小费用最大流)拆边,经典
- Transportation (hdu 3667 最小费用最大流+拆边)
- HDU -- 3667 Transportation(最小费用最大流 )
- HDU 3667 Transportation (最小费用最大流)
- HDU 3667 Transportation (最小费用最大流)
- 最小费用最大流 HDU 1533
- HDU 1853 最小费用最大流
- hdu 1853 最小费用最大流
- hdu 4067 最小费用最大流
- hdu 4411 Arrest(最小费用最大流)
- HDU 1853 最小费用最大流
- HDU 4027 ( 线段树 -- 成段更新)
- HDU 1892 (二维树状数组)
- 嵌入式Linux操作系统名词解释及资源大全
- POJ 2455 二分+最大流
- HDU 3416 最短路+最大流
- HDU 3667 最小费用最大流+拆边
- POJ 3686 最小费用最大流
- 手工命令创建空白android apk
- HDU 3657 Game 网络流--最大独立集
- 分享11个超棒的移动应用开发解决方案
- HDU 1787 欧拉公式
- POJ 1144 Network ---tarjan算法求割点
- POJ 1061 拓展欧几里德算法
- POJ 2115 模线性方程