题目请自行百度.
这道题和sort很像,甚至比sort还水.在此再次吐槽noip模拟题的难度,完全跟noip不是一个级别.
先缩点,求最长路即可.又打了一遍tarjan,应该不会忘了吧.
Code:
{$M 10000000}
program main;
type int=longint;
var
i,j,k,m,n,high,ans:int;
dis,low,dfn,h,tail,w,s,b,a:array[1..500000]of int;
ne,t:array[1..500000]of int;
x,y,tot:int;
function min(x,y:int):int;
begin
if x<y then exit(x)else exit(y);
end;
procedure dfs(x:int);var i,j:int;
begin
inc(high);a[high]:=x;
dfn[x]:=high;low[x]:=dfn[x];
b[x]:=10009;j:=h[x];
while j<>0 do begin
i:=t[j];
if b[i]=0 then begin
dfs(i);low[x]:=min(low[x],low[i]);
end else if b[i]=10009 then begin
low[x]:=min(low[x],dfn[i]);
end;
j:=ne[j];
end;
if low[x]=dfn[x]then begin
for i:=low[x]to high do begin
s[a[i]]:=x;b[a[i]]:=8;a[i]:=0;
end;
high:=low[x]-1;
end;
end;
function relax(x,y:int):boolean;
begin
if dis[y]>=dis[x]+w[y]then exit(false);
dis[y]:=dis[x]+w[y];exit(true);
end;
function spfa(ss:int):int;var l,r:int;
begin
l:=0;r:=1;a[r]:=s[ss];
dis[s[ss]]:=w[s[ss]];
repeat
inc(l);i:=a[l];
j:=h[i];b[k]:=0;
while j<>0 do begin
k:=t[j];
if(k<>i)and(relax(i,k))and(b[k]<>998)then begin
inc(r);a[r]:=k;b[k]:=998;
end;
j:=ne[j];
end;
until l=r;
end;
begin
assign(input,'atm.in');reset(input);
assign(output,'atm.out');rewrite(output);
read(n,m);
for i:=1 to m do begin
read(x,y);inc(tot);
if h[x]=0 then tail[x]:=tot;
t[tot]:=y;ne[tot]:=h[x];h[x]:=tot;
end;
for i:=1 to n do read(w[i]);
for i:=1 to n do if b[i]=0 then dfs(i);
for i:=1 to m do t[i]:=s[t[i]];
for i:=1 to n do if s[i]<>i then begin
ne[tail[s[i]]]:=h[i];h[i]:=0;
tail[s[i]]:=tail[i];w[s[i]]:=w[s[i]]+w[i];
end;
read(x);spfa(x);
read(m);ans:=0;
for i:=1 to m do begin
read(x);
if dis[s[x]]>ans then ans:=dis[s[x]];
end;
write(ans);
close(input);close(output);
end.