第一问不谈,
第二问首先我们要找出哪些是s到t的最短路上的边
由于是无向图,首先正反两遍最短路,求出是s到任意点的距离,任意点到t的距离(即t到任意点的距离);
然后穷举每条边判断是否在最短路上用d[x,y]表示x到y的最短路
则要满足d[s,x]+w(x,y)+d[y,t]=d[s,t],
然后以代价为流量建图跑最小割即可
注意每条无向边边要当做两条有向边考虑;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 const inf=100000007; 2 type node=record 3 from,point,next,flow:longint; 4 end; 5 6 var edge:array[0..130000] of node; 7 ans1,ans2:array[0..60010] of longint; 8 p,cur,pre,numh,h,low,dfn,be,st:array[0..5010] of longint; 9 tot,d,r,x,y,z,i,j,n,m,s,t,len:longint; 10 v,f:array[0..5010] of boolean; 11 12 function min(a,b:longint):longint; 13 begin 14 if a>b then exit(b) else exit(a); 15 end; 16 17 procedure add(x,y,f:longint); 18 begin 19 inc(len); 20 edge[len].point:=y; 21 edge[len].from:=x; 22 edge[len].flow:=f; 23 edge[len].next:=p[x]; 24 p[x]:=len; 25 end; 26 27 procedure sap; 28 var u,i,j,tmp,neck,q:longint; 29 begin 30 u:=s; 31 numh[0]:=n; 32 while h[s]<n do 33 begin 34 if u=t then 35 begin 36 i:=s; 37 neck:=inf; 38 while i<>t do 39 begin 40 j:=cur[i]; 41 if neck>edge[j].flow then 42 begin 43 neck:=edge[j].flow; 44 q:=i; 45 end; 46 i:=edge[j].point; 47 end; 48 i:=s; 49 while i<>t do 50 begin 51 j:=cur[i]; 52 dec(edge[j].flow,neck); 53 inc(edge[j xor 1].flow,neck); 54 i:=edge[j].point; 55 end; 56 u:=q; 57 end; 58 q:=-1; 59 i:=p[u]; 60 while i<>-1 do 61 begin 62 j:=edge[i].point; 63 if (edge[i].flow>0) and (h[u]=h[j]+1) then 64 begin 65 q:=i; 66 break; 67 end; 68 i:=edge[i].next; 69 end; 70 if q<>-1 then 71 begin 72 cur[u]:=q; 73 pre[j]:=u; 74 u:=j; 75 end 76 else begin 77 dec(numh[h[u]]); 78 if numh[h[u]]=0 then exit; 79 tmp:=n; 80 i:=p[u]; 81 while i<>-1 do 82 begin 83 j:=edge[i].point; 84 if edge[i].flow>0 then tmp:=min(tmp,h[j]); 85 i:=edge[i].next; 86 end; 87 h[u]:=tmp+1; 88 inc(numh[h[u]]); 89 if u<>s then u:=pre[u]; 90 end; 91 end; 92 end; 93 94 procedure tarjan(x:longint); 95 var i,y:longint; 96 begin 97 v[x]:=true; 98 f[x]:=true; 99 inc(r); 100 inc(d); 101 st[r]:=x; 102 dfn[x]:=d; 103 low[x]:=d; 104 i:=p[x]; 105 while i<>-1 do 106 begin 107 y:=edge[i].point; 108 if edge[i].flow>0 then 109 begin 110 if not v[y] then 111 begin 112 tarjan(y); 113 low[x]:=min(low[x],low[y]); 114 end 115 else if f[y] then 116 low[x]:=min(low[x],low[y]); 117 end; 118 i:=edge[i].next; 119 end; 120 if low[x]=dfn[x] then 121 begin 122 inc(tot); 123 while st[r+1]<>x do 124 begin 125 y:=st[r]; 126 f[y]:=false; 127 be[y]:=tot; 128 dec(r); 129 end; 130 end; 131 end; 132 133 begin 134 readln(n,m,s,t); 135 len:=-1; 136 fillchar(p,sizeof(p),255); 137 for i:=1 to m do 138 begin 139 readln(x,y,z); 140 add(x,y,z); 141 add(y,x,0); 142 end; 143 sap; 144 for i:=1 to n do 145 if not v[i] then 146 begin 147 r:=0; 148 d:=0; 149 tarjan(i); 150 end; 151 i:=0; 152 while i<=len do 153 begin 154 if (edge[i].flow=0) then 155 begin 156 x:=edge[i].from; 157 y:=edge[i].point; 158 if be[x]<>be[y] then 159 begin 160 ans1[i div 2+1]:=1; 161 if (be[x]=be[s]) and (be[y]=be[t]) or (be[x]=be[t]) and (be[y]=be[s]) then 162 ans2[i div 2+1]:=1; 163 end; 164 end; 165 i:=i+2; 166 end; 167 for i:=1 to m do 168 writeln(ans1[i],' ',ans2[i]); 169 end.