太神了直接看了hzwer的题解,有个新认识,一条路径上满流的一定是这条路径上所有边的最小值。
type arr=record toward,next,cap,from:longint; end; const maxm=200000; maxn=10000; var edge:array[0..maxm]of arr; first,cur,d,p,gap:array[0..maxn]of longint; chose1,chose2:array[0..maxn]of boolean; n,m,s,t,tot,esum:longint; function min(x,y:longint):longint; begin if x<y then exit(x); exit(y); end; procedure add(j,k,l:longint); begin inc(esum); edge[esum].from:=j; edge[esum].toward:=k; edge[esum].next:=first[j]; first[j]:=esum; edge[esum].cap:=l; end; procedure addedge(j,k,l:longint); begin add(j,k,l); add(k,j,0); end; function sap(x,flow:longint):longint; var now,more,i,too:longint; begin if x=t then exit(flow); now:=0; i:=cur[x]; while i>=0 do begin too:=edge[i].toward; if (d[x]=d[too]+1) and (edge[i].cap>0) then begin more:=sap(too,min(flow-now,edge[i].cap)); dec(edge[i].cap,more); inc(edge[i xor 1].cap,more); inc(now,more); cur[x]:=i; if now=flow then exit(flow); end; i:=edge[i].next; end; dec(gap[d[x]]); if gap[d[x]]=0 then d[s]:=n; inc(d[x]); inc(gap[d[x]]); cur[x]:=first[x]; exit(now); end; procedure maxflow; var i:longint; begin fillchar(d,sizeof(d),0); fillchar(gap,sizeof(gap),0); gap[0]:=n; for i:=1 to n do cur[i]:=first[i]; while d[s]<n do sap(s,maxlongint); end; procedure into; var i,j,k,l:longint; begin esum:=-1; fillchar(first,sizeof(first),255); readln(n,m,s,t); for i:=1 to m do begin readln(j,k,l); addedge(j,k,l); end; end; procedure work; var head,tail,x,y,i,j,too:longint; begin maxflow; { for i:=0 to m<<1 do writeln(edge[i].from,' ',edge[i].toward,' ',edge[i].next,' ',edge[i].cap); } head:=1; tail:=1; p[1]:=s; fillchar(chose1,sizeof(chose1),false); chose1[s]:=true; while head<=tail do begin x:=p[head]; i:=first[x]; while i>=0 do begin too:=edge[i].toward; if (edge[i].cap>0) and (not chose1[too]) then begin inc(tail); p[tail]:=too; chose1[too]:=true; end; i:=edge[i].next; end; inc(head); end; //for i:=1 to n do writeln(i,' ',chose1[i]); head:=1; tail:=1; p[1]:=t; fillchar(chose2,sizeof(chose2),false); chose2[t]:=true; while head<=tail do begin x:=p[head]; i:=first[x]; while i>=0 do begin too:=edge[i].toward; if (edge[i xor 1].cap>0) and (not chose2[too]) then begin inc(tail); p[tail]:=too; chose2[too]:=true; end; i:=edge[i].next; end; inc(head); end; //for i:=1 to n do writeln(i,' ',chose2[i]); for i:=1 to m do begin j:=(i-1)<<1; if edge[j].cap>0 then begin writeln(0,' ',0); continue; end; x:=edge[j].from; y:=edge[j].toward; if not ( (chose1[x] and chose1[y]) or (chose2[x] and chose2[y]) )then write(1) else write(0); write(' '); if (chose1[x] and chose2[y]) or (chose1[y] and chose2[x])then writeln(1) else writeln(0); end; readln; end; begin into; work; end.