题目要求从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.