【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.
原文地址:https://www.cnblogs.com/EC-Ecstasy/p/4224944.html