【HDOJ6118】度度熊的交易计划(费用流)
题意:
度度熊参与了喵哈哈村的商业大会,但是这次商业大会遇到了一个难题:
喵哈哈村以及周围的村庄可以看做是一共由n个片区,m条公路组成的地区。
由于生产能力的区别,第i个片区能够花费a[i]元生产1个商品,但是最多生产b[i]个。
同样的,由于每个片区的购买能力的区别,第i个片区也能够以c[i]的价格出售最多d[i]个物品。
由于这些因素,度度熊觉得只有合理的调动物品,才能获得最大的利益。
据测算,每一个商品运输1公里,将会花费1元。
那么喵哈哈村最多能够实现多少盈利呢?
1<=n<=500,
1<=m<=1000,
1<=a[i],b[i],c[i],d[i],k[i]<=1000,
1<=u[i],v[i]<=n
思路:明显的一个最小费用流模型 写的是最大费用流,注意没有要求流量最大
刚开始TooNaive先跑了一波最短路然后建的图
而后发现直接照原图建边,费用流过程中就会自动调整到最短路上
还是要学习一个
SPFA找的时候如果当前继续跑流会使利润减小就停止,即dis[src]<0
1 const inf=10000000000000000000; 2 var q:array[0..10000]of longint; 3 f:array[1..1000,1..1000]of longint; 4 a,b,c,d,dis:array[1..1000]of longint; 5 head,vet,len1,len2,next:array[1..600000]of longint; 6 pre:array[0..10000,1..2]of longint; 7 inq:array[0..1000]of boolean; 8 fan:array[0..600000]of longint; 9 n,m,i,tot,t1,s,source,src,x,y,z,j:longint; 10 ans1,ans2:int64; 11 12 13 procedure add(a,b,c,d:longint); 14 begin 15 inc(tot); 16 next[tot]:=head[a]; 17 vet[tot]:=b; 18 len1[tot]:=c; 19 len2[tot]:=d; 20 head[a]:=tot; 21 end; 22 23 function min(x,y:int64):int64; 24 begin 25 if x<y then min:=x 26 else min:=y; 27 end; 28 29 function spfa:boolean; 30 var u,e,v,t,w,i:longint; 31 begin 32 for i:=1 to s do 33 begin 34 dis[i]:=-(maxlongint>>1); 35 inq[i]:=false; 36 end; 37 t:=0; w:=1; q[1]:=source; dis[source]:=0; inq[source]:=true; 38 while t<w do 39 begin 40 inc(t); u:=q[t mod 10000]; inq[u]:=false; 41 e:=head[u]; 42 while e<>0 do 43 begin 44 v:=vet[e]; 45 if (len1[e]>0)and(dis[u]+len2[e]>dis[v]) then 46 begin 47 dis[v]:=dis[u]+len2[e]; 48 pre[v,1]:=u; 49 pre[v,2]:=e; 50 if not inq[v] then 51 begin 52 inc(w); q[w mod 10000]:=v; inq[v]:=true; 53 end; 54 end; 55 e:=next[e]; 56 end; 57 end; 58 //if dis[src]=-(maxlongint>>1) then spfa:=false 59 // else spfa:=true; 60 if dis[src]<0 then spfa:=false 61 else spfa:=true; 62 end; 63 64 procedure mcf; 65 var k,e:longint; 66 t:int64; 67 begin 68 k:=src; t:=1<<55; 69 while k<>source do 70 begin 71 t:=min(t,len1[pre[k,2]]); 72 k:=pre[k,1]; 73 end; 74 k:=src; 75 while k<>source do 76 begin 77 e:=pre[k,2]; 78 len1[e]:=len1[e]-t; 79 len1[fan[e]]:=len1[fan[e]]+t; 80 ans2:=ans2+t*len2[e]; 81 k:=pre[k,1]; 82 end; 83 end; 84 85 begin 86 assign(input,'1005.in'); reset(input); 87 assign(output,'1005.out'); rewrite(output); 88 for i:=1 to 600000 do 89 if i and 1=1 then fan[i]:=i+1 90 else fan[i]:=i-1; 91 while not eof do 92 begin 93 read(n,m); 94 tot:=0; 95 if (n=0)and(m=0) then break; 96 for i:=1 to n do read(a[i],b[i],c[i],d[i]); 97 tot:=0; 98 for i:=1 to n do head[i]:=0; 99 source:=n+1; src:=n+2; s:=n+2; 100 for i:=1 to n do 101 begin 102 add(source,i,b[i],-a[i]); 103 add(i,source,0,a[i]); 104 end; 105 for i:=1 to n do 106 begin 107 add(i,src,d[i],c[i]); 108 add(src,i,0,-c[i]); 109 end; 110 111 for i:=1 to m do 112 begin 113 read(x,y,z); 114 add(x,y,maxlongint,-z); 115 add(y,x,0,z); 116 add(y,x,maxlongint,-z); 117 add(x,y,0,z); 118 end; 119 ans1:=0; ans2:=0; 120 while spfa do mcf; 121 writeln(ans2); 122 for i:=1 to s do head[i]:=0; 123 for i:=1 to s do dis[i]:=0; 124 for i:=1 to s do 125 for j:=1 to 2 do pre[i,j]:=0; 126 end; 127 close(input); 128 close(output); 129 130 end.
null