poj2135Farm Tour 最小費用最大流

2021-06-29 04:16:50 字數 2607 閱讀 4379

題目要求從1到n走一遍再從n到1走一遍而且有重邊,相當於從1到n走兩邊

所以加乙個源點0<-->1,費用為0,流量為2

加乙個匯點n+1<-->n,費用為0,流量為2

中間的邊流量為1(只走一遍),費用為c

然後一遍0->n+1的費用流

要注意是無向圖,所以乙個輸入有4條邊

a->b ,c,1

b->a ,-c,0

b->a ,c,1

a->b ,c,0

type point=record

a,b,c,f,o,p:longint; //o是反邊編號

end;

var edge:array[1..40010]of point;

n,i,m,a,b1,c,l,cost,top,tail,p,j,min,ttf,ff:longint;

head,d,pre,re:array[0..10010]of longint;

f:array[0..10010]of boolean;

b:array[1..100000]of longint;

procedure add(u,v,c,f:longint);//新增邊用過程

begin

l:=l+1;

edge[l].a:=u;

edge[l].b:=v;

edge[l].c:=c;

edge[l].f:=f;

edge[l].o:=l+1;

edge[l].p:=head[u];

head[u]:=l;

l:=l+1;

edge[l].a:=v;

edge[l].b:=u;

edge[l].c:=-c;

edge[l].f:=0;

edge[l].o:=l-1;

edge[l].p:=head[v];

head[v]:=l;

end;

begin

read(n,m);

for i:=0 to n+1 do head[i]:=-1;

for i:=1 to m do

begin

read(a,b1,c);

add(a,b1,c,1);

add(b1,a,c,1); //無向圖

end;

add(0,1,0,2);

add(n,n+1,0,2);

cost:=0;ttf:=0;

while true do//!!

begin

top:=1;tail:=1;

fillchar(b,sizeof(b),0);

b[top]:=0;

for i:=0 to n+1 do d[i]:=maxlongint;

d[0]:=0;

fillchar(f,sizeof(f),true);

f[0]:=false;

fillchar(pre,sizeof(pre),0);

pre[0]:=-1;

fillchar(re,sizeof(re),0);//記錄i與前驅的邊的編號

repeat//spfa

p:=head[b[top]];

while p<>-1 do

begin

j:=edge[p].b;

if (d[j]>d[b[top]]+edge[p].c)and(edge[p].f>0) then

begin

d[j]:=d[b[top]]+edge[p].c;

pre[j]:=b[top];//!不要寫錯b[top]

re[j]:=p;

if f[j] then

begin

f[j]:=false;

tail:=tail+1;

b[tail]:=j;

end;

end;

p:=edge[p].p;

end;

f[b[top]]:=true;

top:=top+1;

until top>tail;

if d[n+1]=maxlongint then break; //如果找不到可擴充的流,就結束

min:=maxlongint;

i:=n+1; //這個一定要寫

while pre[i]<>-1 do

begin

if min>edge[re[i]].f then min:=edge[re[i]].f;

i:=pre[i]; //這個一定要寫

end;

i:=n+1;

while pre[i]<>-1 do

begin

edge[re[i]].f:=edge[re[i]].f-min;

edge[edge[re[i]].o].f:=edge[edge[re[i]].o].f+min;

cost:=cost+edge[re[i]].c*min;

i:=pre[i];

end;

//ttf:=ttf+min;

end;

//writeln(ttf);

writeln(cost);

readln;readln;

end.

POJ 2135 Farm Tour 最小費用流

若不是看了題目分類,很難想到這題和網路流掛上鉤,乍一看是求2遍最短路,但是很明顯求最短路可能是錯誤的。題意 fj 又是他 想帶朋友參觀自己的農場,農場有n個點,m條邊,要從1點到n點,再從n點走回來,且2次不能走相同的路,問最小的花費時間。題解 費用流,最小費用即為答案 我的構圖方法 定義源點和匯點...

POJ 2135 Farm Tour 最小費用流

題意 n個點,m條邊,從1號點出發到n號點,再走回來,且不能走走過的路,求最小路徑權和 最小費用流,用流量為1 限制每條邊只能走一次,建立超源匯點,源點連1號點的流量為2,費用0,匯點同理。其他邊的流量為1,費用為權值。建立超源匯點且權值為2目的是因為起終點經過2次 雖然這裡是點經過2次而題目是邊 ...

POJ 2135 Farm Tour 最小費用流

很容易看出來時最小費用流,但這裡要注意是無向邊,所以要建立兩條邊。為了滿足退流時,花費還是最小,反向邊的花費要為相反數。1 status g ac 32ms 980kb 2 include3 include4 include 5 include6 include7 include 8 include...