【BZOJ1179】[Apio2009]Atm (tarjan+SPFA)
显而易见的tarjan+spfa...不解释了
1 const maxn=500419; 2 type 3 edgetype=record 4 toward,next:longint; 5 end; 6 7 var 8 edge1,edge2:array[0..maxn] of edgetype; 9 first1,first2,scc,stack,dfn,low,val,sum,q,d:Array[0..maxn] of longint; 10 pd:array[0..maxn] of boolean; 11 num,tot,n,m,cnt,top:longint; 12 13 function min(x,y:longint):longint; begin if x<y then exit(x) else exit(y); end; 14 15 procedure addedge(i,j:longint); 16 begin 17 inc(tot); 18 edge1[tot].toward:=j; 19 edge1[tot].next:=first1[i]; 20 first1[i]:=tot; 21 end; 22 23 procedure add(i,j:longint); 24 begin 25 inc(tot); 26 edge2[tot].toward:=j; 27 edge2[tot].next:=first2[i]; 28 first2[i]:=tot; 29 end; 30 31 procedure tarjan(v:longint); 32 var i,tmp,u:longint; 33 begin 34 inc(cnt); dfn[v]:=cnt; low[v]:=cnt; 35 inc(top); stack[top]:=v; 36 pd[v]:=true; i:=first1[v]; 37 while i<>0 do 38 begin 39 tmp:=edge1[i].toward; 40 if dfn[tmp]=0 then 41 begin 42 tarjan(tmp); 43 low[v]:=min(low[v],low[tmp]); 44 end 45 else if pd[tmp] then low[v]:=min(low[v],dfn[tmp]); 46 i:=edge1[i].next; 47 end; 48 if low[v]=dfn[v] then 49 begin 50 inc(num); 51 repeat 52 u:=stack[top]; dec(top); 53 pd[u]:=false; scc[u]:=num; 54 inc(sum[num],val[u]); 55 until u=v; 56 end; 57 end; 58 59 procedure spfa(s:longint); 60 var head,tail,i,j,tmp:longint; 61 begin 62 fillchar(d,sizeof(d),0); 63 fillchar(pd,sizeof(pd),false); 64 head:=0; 65 tail:=1; 66 pd[scc[s]]:=true; 67 q[1]:=scc[s]; 68 d[scc[s]]:=sum[scc[s]]; 69 while head<>tail do 70 begin 71 inc(head); 72 if head>maxn then head:=1; 73 j:=q[head]; 74 i:=first2[j]; 75 while i<>0 do 76 begin 77 tmp:=edge2[i].toward; 78 if d[j]+sum[tmp]>d[tmp] then 79 begin 80 d[tmp]:=d[j]+sum[tmp]; 81 if not pd[tmp] then 82 begin 83 inc(tail); if tail>maxn then tail:=1; 84 q[tail]:=tmp; 85 pd[tmp]:=true; 86 end; 87 end; 88 i:=edge2[i].next; 89 end; 90 pd[j]:=false; 91 end; 92 end; 93 94 procedure init; 95 var i,j,a,b:longint; 96 begin 97 read(n,m); 98 for i:= 1 to m do 99 begin 100 readln(a,b); 101 addedge(a,b); 102 end; 103 for i:= 1 to n do read(val[i]); 104 for i:= 1 to n do if dfn[i]=0 then tarjan(i); 105 end; 106 107 procedure solve; 108 var p,x,ans,s,i,j:longint; 109 begin 110 read(s,p); 111 tot:=0; 112 for j:= 1 to n do 113 begin 114 i:=first1[j]; 115 while i<>0 do 116 begin 117 x:=edge1[i].toward; 118 if scc[x]<>scc[j] then add(scc[j],scc[x]); 119 i:=edge1[i].next; 120 end; 121 end; 122 spfa(s); 123 ans:=0; 124 for i:= 1 to p do 125 begin 126 read(x); 127 if d[scc[x]]>ans then ans:=d[scc[x]]; 128 end; 129 writeln(ans); 130 end; 131 132 Begin 133 init; 134 solve; 135 End.