hdu 3667 Transportation (拆边 ,最小费用流)

http://acm.hdu.edu.cn/showproblem.php?pid=3667

题意:

用 0 到 n-1 运送k 个货物,m条边,每条边,u,v,a,c,;  每条边表示 运送 x 单元货物的花费为  a * x*x,c 表示最大流量 ,

求 最小费用  ,若不能全部运送输出 -1;

 

题解:  拆边 ,看到这个题直接的思路就是费用流,一开始提了个模版 上去 发现不对,我们以前做的  花费是  a*f  ,而现在是  a*f*f(此时 以 最短路 已不能找到正确的答案);

所以我们要变为  a*f  ,那么就是,我们 发现 第一次运送时

费用为a,第二次取这条路时费用为3a(即流量为2时费用值为a+3a=4a),……,第i次取这条路时费用为(2*i-1)*a

在   u  到  u  连  c  条边,每条边的流量 为 1 ,费用   (2*i - 1)*a

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <cmath>
  6 #include <queue>
  7 #include <stack>
  8 #include < set>
  9 #include <map>
 10 #include < string>
 11 
 12  #define CL(a,num) memset((a),(num),sizeof(a))
 13  #define iabs(x)  ((x) > 0 ? (x) : -(x))
 14  #define Min(a , b) ((a) < (b) ? (a) : (b))
 15  #define Max(a , b) ((a) > (b) ? (a) : (b))
 16 
 17  #define ll __int64
 18  #define inf 0x7f7f7f7f
 19  #define MOD 100000007
 20  #define lc l,m,rt<<1
 21  #define rc m + 1,r,rt<<1|1
 22  #define pi acos(-1.0)
 23  #define test puts("<------------------->")
 24  #define maxn 200
 25  #define M 507
 26  #define N 200
 27  using  namespace std;
 28  // freopen("din.txt","r",stdin);
 29 
 30 
 31  struct node
 32 {
 33      int u,v;
 34      int c,w;
 35      int next;
 36 }g[maxn* 1000];
 37  int head[maxn],cnt,pre[maxn];
 38  int dis[maxn];
 39  bool inq[maxn];
 40  int n,m,k,s,t,ans,res;
 41 
 42 
 43  void add( int u, int v, int c, int w){
 44     g[cnt].u = u; g[cnt].v = v; g[cnt].c = c; g[cnt].w = w;
 45     g[cnt].next = head[u]; head[u] = cnt++;
 46 
 47     g[cnt].u = v; g[cnt].v = u; g[cnt].c =  0; g[cnt].w = -w;
 48     g[cnt].next = head[v]; head[v] = cnt++;
 49 }
 50  void spfa(){
 51      int i;
 52 
 53     queue< int>q;
 54      for (i =  0; i <= t; ++i){
 55         dis[i] = inf;
 56         inq[i] =  false;
 57         pre[i] = - 1;
 58     }
 59     q.push(s); inq[s] =  true;
 60     dis[s] =  0;
 61      while (!q.empty()){
 62          int u = q.front(); q.pop();
 63         inq[u] =  false;
 64 
 65          for (i = head[u]; i != - 1; i = g[i].next){
 66              int v = g[i].v;
 67              if (g[i].c && dis[v] > dis[u] + g[i].w){
 68                 dis[v] = dis[u] + g[i].w;
 69                 pre[v] = i; // 注意这里记录的是这一条边了
 70                   if (!inq[v]){
 71                     inq[v] =  true;
 72                     q.push(v);
 73                 }
 74             }
 75         }
 76     }
 77 }
 78  void mcmf(){
 79     ans =  0;
 80     res =  0 ;
 81 
 82     while ( 1){
 83        spfa();
 84         if (pre[t] == - 1break;
 85         int x = t,minf = inf;
 86         while (x != s){
 87            minf = min(minf,g[pre[x]].c);
 88 
 89            x = g[pre[x]].u;
 90 
 91        }
 92        x = t;
 93         while (x != s){
 94            g[pre[x]].c -= minf;
 95            g[pre[x]^ 1].c += minf;
 96 
 97            x = g[pre[x]].u;
 98        }
 99         ans += minf*minf*dis[t];
100         res += minf;
101 
102    }
103     
104 }
105 
106 
107  void init()
108 {
109 
110     memset(head,- 1, sizeof(head));
111     cnt =  0;
112 }
113 
114  int main()
115 {
116      int u,v,a,flow ,i,j;
117      while(scanf( " %d%d%d ",&n,&m,&k)!=EOF)
118     {
119         init() ;
120 
121          for(i =  0;i< m;i++)
122         {
123             scanf( " %d%d%d%d ",&u,&v,&a,&flow);
124 
125             
126              for(j =  0 ; j< flow;j++)
127                  add(u,v, 1,a*( 2*j +  1));
128 
129         }
130 
131         add( 0, 1,k, 0) ;
132       
133         s =  0;
134         t = n ;
135         mcmf() ;
136          if(res < k)printf( " -1\n ");
137          else
138         {
139             printf( " %d\n ",ans) ;
140         }
141     }
142 }

 

 

转载于:https://www.cnblogs.com/acSzz/archive/2012/10/14/2723368.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值