Tarjan缩环,跑spfa最长路。
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
const int N=500005*2;
struct arr{
int node,nxt;
}e1[N],e2[N];
int h[N],head[N],tim,tot1,tot2,scc,dfn[N],low[N];
int q[N],l,r,data[N],val[N],n,m,p,S,belong[N],x,y,ans,f[N];
bool bar[N],check[N];
int stack[N],top;
void add1(int x,int y){
e1[++tot1].node=y;
e1[tot1].nxt=h[x];
h[x]=tot1;
}
void add2(int x,int y) {e2[++tot2].node=y;e2[tot2].nxt=head[x];head[x]=tot2;}
int get(){
char x=getchar();int p=0;
while (x<'0' || x>'9') x=getchar();
while (x>='0' && x<='9') p=p*10+x-'0',x=getchar();
return p ;
}
void init(){
memset(h,0,sizeof h);
memset(bar,0,sizeof bar);
n=get();m=get();
for (int i=1;i<=m;i++){
x=get();y=get();
add1(x,y);
}
for (int i=1;i<=n;i++) data[i]=get();
S=get();p=get();
}
void tarjan(int t){
low[t]=dfn[t]=++tim;
check[t]=1;
stack[++top]=t;
for (int i=h[t];i;i=e1[i].nxt){
int x=e1[i].node;
if (!dfn[x]){
tarjan(x);
low[t]=min(low[t],low[x]);
}else if (check[x]){
low[t]=min(low[t],dfn[x]);
}
}
if (low[t]==dfn[t]){
int now=0;
scc++;
while (now!=t){
now=stack[top--];
belong[now]=scc;
val[scc]+=data[now];
check[now]=0;
}
}
}
void rebuild(){
for (int i=1;i<=n;i++)
for (int j=h[i],k;j;j=e1[j].nxt){
k=e1[j].node;
if (belong[k]!=belong[i]) add2(belong[i],belong[k]);
}
}
void spfa(){
memset(check,0,sizeof check);
memset(q,0,sizeof q);
int u,v;
S=belong[S];l=0;r=1;q[0]=S;
f[S]=val[S];check[S]=1;
while (l!=r) {
u=q[l];l++;l%=500000;
for (int i=head[u];i;i=e2[i].nxt){
v=e2[i].node;
if (f[u]+val[v]>f[v]){
f[v]=f[u]+val[v];
if (!check[v]){
check[v]=1;
q[r]=v;r++;r%=500000;
}
}
}
check[u]=0;
}
}
int main(){
init();
for (int i=1;i<=n;i++)
if (!dfn[i]) tarjan(i);
rebuild();
spfa();
for (int i=1;i<=p;i++)
ans=max(ans,f[belong[get()]]);
printf("%d\n",ans);
return 0;
}