【NOIP2016提高A组模拟9.9】爬山

时间:2023-01-06 19:09:02

//真想把这道题@#@#@##$#@%#*啊!!!!!!!
Description

国家一级爬山运动员h10今天获得了一张有着密密麻麻标记的地图,在好奇心的驱使下,他又踏上了去爬山的路。
对于爬山,h10有一个原则,那就是不走回头路,于是他把地图上的所有边都标记成了有向边。他决定从点S出发,每到达一个新的节点他就可以获得一定的成就值。同时h10又是一个很珍惜时间的运动员,他不希望这次爬山的成就值白白浪费,所以最后他一定要在一个存档点停下,保存自己的成就值。
请你计算出在此次爬山运动中h10能够得到的最大成就值。保证h10能走到存档点。

Input

第一行两个整数 N,M,表示点数和边数。
接下来 M 行,每行两个整数 u,v,表示u到v有一条有向边(没有自环)。
第 M+2 行 N 个正整数,表示每个点的成就值。
接下来一行两个整数 S,p,表示出发点和存档点个数。
下面一行 p 个整数,表示存档点。

Output

一个正整数,表示最大成就值。

Sample Input

5 7
5 1
3 1
2 5
3 5
4 3
4 2
4 5
7 6 3 2 2
4 3
1 5 2

Sample Output

17

Data Constraint

对于 30% 的数据, N,M≤1000,并且地图为有向无环图。
对于 100% 的数据, N,M≤500000。(数据有梯度,注意答案的大小)

比赛时の想法

tarjan缩环后用dfs求出答案,70%

正解

首先,tarjan只要从开始位置开始做一次就可以了,而我一开始把每个没有有向边连向这个点的都tarjan了一遍,超慢哎!
tarjan要用非递归式的,否则会爆栈
tarjan完之后就重新连一下边,然后随便跑个dfs什么的求出答案就可以了
注意开int64哦~~

贴代码

感受终极恐惧吧!!!

var
a,b:array[0..500005,1..2]of longint;
h,fen,cc:array[0..500005]of int64;
h1,h2,h4,cy,dfn,low,t:array[0..500005]of longint;
bb,bz,bk,h3,pig:array[0..500005]of boolean;
i,j,k,l,n,m,top,p,s,t1,tc,nod:longint;
procedure qsort(l,r:longint);inline;
var
i,j,mid:longint;
begin
i:=l;
j:=r;
mid:=a[(i+j) div 2,1];
repeat
while a[i,1]<mid do inc(i);
while a[j,1]>mid do dec(j);
if i<=j then
begin
a[0]:=a[i];
a[i]:=a[j];
a[j]:=a[0];
inc(i);
dec(j);
end;
until i>j;
if i<r then qsort(i,r);
if l<j then qsort(l,j);
end;
procedure star;inline;
begin
b[a[1,1],1]:=1;
for i:=2 to m do
if a[i,1]<>a[i-1,1] then
begin
b[a[i-1,1],2]:=i-1;
b[a[i,1],1]:=i;
end;
b[a[m,1],2]:=m;
end;
procedure tarjan;inline;
var
i,t,kc,x:longint;
begin
while nod>0 do
begin
x:=h1[nod];
if h3[x]=false then
begin
inc(top);
inc(tc);
cc[top]:=x;
dfn[x]:=tc;
low[x]:=tc;
bb[x]:=true;
bz[x]:=true;
end;
if h4[nod]>b[x,1] then if low[a[h4[nod]-1,2]]<low[x] then low[x]:=low[a[h4[nod]-1,2]];
for i:=h4[nod] to b[x,2] do
if i<>0 then
begin
if bz[a[i,2]]=false then
begin
//tarjan(a[i,2]);
h4[nod]:=i+1;
break;

end else
if (low[x]>dfn[a[i,2]]) and (bb[a[i,2]]=true) then low[x]:=dfn[a[i,2]];
end;
if h4[nod]=i+1 then
begin
h3[x]:=true;
inc(nod);
h1[nod]:=a[i,2];
h2[nod]:=nod-1;
h4[nod]:=b[a[i,2],1];
continue;
end;
if low[x]=dfn[x] then
begin
inc(p);
while cc[top+1]<>x do
begin
bb[cc[top]]:=false;
cy[cc[top]]:=p;
dec(top);
end;
end;
nod:=h2[nod];
end;
end;
procedure dfs(x:longint);
var
i:longint;
begin
for i:=b[x,1] to b[x,2] do
if (i<>0) and (bz[a[i,2]]=false) then
begin
if fen[x]+cc[a[i,2]]>fen[a[i,2]] then
fen[a[i,2]]:=fen[x]+cc[a[i,2]];
bz[a[i,2]]:=true;
dfs(a[i,2]);
bz[a[i,2]]:=false;
end;
end;
procedure init;
begin
assign(input,'t2.in'); reset(input);
readln(n,m);
for i:=1 to m do
begin
readln(a[i,1],a[i,2]);
bk[a[i,2]]:=true;
pig[a[i,1]]:=true;
pig[a[i,2]]:=true;
end;
qsort(1,m);
star;
if bk[a[1,1]]=true then
begin
bk[a[1,1]]:=false;
for i:=2 to a[m,1] do if bk[i]=false then bk[a[1,1]]:=true;
end;
for i:=1 to n do read(fen[i]);
readln;
read(s);
for i:=1 to a[m,1] do
if (bz[i]=false) and (bk[i]=false) and (pig[i]=true) then
begin
top:=0;
nod:=1;
h1[1]:=i;
h2[1]:=0;
h4[1]:=b[i,1];
fillchar(h3,sizeof(h3),false);
tarjan();
if bz[s]=true then break;
end;
for i:=1 to a[m,1] do
if (bz[i]=false) and (pig[i]=true) then
begin
if bz[s]=true then break;
top:=0;
nod:=1;
h1[1]:=i;
h2[1]:=0;
fillchar(h3,sizeof(h3),false);
tarjan();
end;
for i:=1 to m do
begin
a[i,1]:=cy[a[i,1]];
a[i,2]:=cy[a[i,2]];
end;
qsort(1,m);
fillchar(b,sizeof(b),0);
star;
fillchar(cc,sizeof(cc),0);
for i:=1 to n do cc[cy[i]]:=cc[cy[i]]+fen[i];
readln(t1);
s:=cy[s];
fillchar(bb,sizeof(bb),false);
for i:=1 to t1 do
begin
read(t[i]);
t[i]:=cy[t[i]];
bb[t[i]]:=true;
end;
end;
begin
init;
fillchar(bz,sizeof(bz),false);
fillchar(fen,sizeof(fen),0);
fen[s]:=cc[s];
bz[s]:=true;
dfs(s);
if bb[1]=false then fen[1]:=0;
for i:=0 to p do
if (fen[i]>fen[1]) and (bb[i]=true) then fen[1]:=fen[i];
writeln(fen[1]);
close(input);
end.