【链接】
bzoj1179
【解题报告】
Tarjan裸题。
再刷一遍最短路即可。
#include<cstdio>
#include<cstring>
const int maxn=500005,maxm=500005,maxp=1005;
int n,m,P,ti,st,who[maxp],mo[maxn],father[maxn],E[2],son[maxm][2],nxt[maxm][2],lnk[maxn][2],ans,distz[maxn],len_b;
int dfn[maxn],low[maxn],stack_[maxn],top,que[maxn];
bool instack[maxn],vis[maxn];
bool Eoln(char ch) {return ch==10||ch==13||ch==EOF;}
inline int readi(int &x)
{
int tot=0,f=1;
char ch=getchar();if (ch==EOF) return 2;
while ('9'<ch||ch<'0') {if (ch=='-') f=-f;ch=getchar();}
while ('0'<=ch&&ch<='9') tot=tot*10+ch-48,ch=getchar();
x=tot*f;
return Eoln(ch);
}
int min2(int x,int y) {return x<y? x:y;}
void Tarjan(int x)
{
int j,y;
dfn[x]=++ti;low[x]=ti;instack[x]=true;stack_[++top]=x;
for (j=lnk[x][0];j;j=nxt[j][0])
if (dfn[son[j][0]]==0)
{
Tarjan(son[j][0]);
low[x]=min2(low[x],low[son[j][0]]);
} else if (instack[son[j][0]]) low[x]=min2(low[x],dfn[son[j][0]]);
if (dfn[x]==low[x])
do
{
y=stack_[top--];
instack[y]=false;father[y]=x;
if (x!=y) mo[x]+=mo[y];
} while (x!=y);
}
void swapi(int &x,int &y) {int t=x;x=y;y=t;}
void Faster(int x,int y) {if (distz[y]>distz[x]) swapi(que[x],que[y]);}
void Spfa()
{
int j,k,MAX,x,headz=0,tailz=1;
memset(distz,192,sizeof(distz));
distz[st]=mo[st];que[tailz]=st;vis[st]=true;
while (headz!=tailz)
{
headz=(headz+1)%maxn;x=que[headz];
vis[x]=false;
for (j=lnk[x][1];j;j=nxt[j][1])
if (distz[x]+mo[son[j][1]]>distz[son[j][1]])
{
distz[son[j][1]]=distz[x]+mo[son[j][1]];
if (!vis[son[j][1]])
{
vis[son[j][1]]=true;
tailz=(tailz+1)%maxn;que[tailz]=son[j][1];
Faster((headz+1)%maxn,tailz);
}
}
}
}
void add(int x,int y,int id) {son[++E[id]][id]=y;nxt[E[id]][id]=lnk[x][id];lnk[x][id]=E[id];}
int main()
{
int i,j,x,y,fi,fj;
freopen("1179.in","r",stdin);
freopen("1179.out","w",stdout);
readi(n);readi(m);
for (i=1;i<=m;i++)
{
readi(x);readi(y);
add(x,y,0);
}
for (i=1;i<=n;i++) readi(mo[i]);
readi(st);readi(P);
for (i=1;i<=P;i++) readi(who[i]);
for (i=1;i<=n;i++) if (dfn[i]==0) Tarjan(i);
for (i=1;i<=n;i++)
{
fi=father[i];
for (j=lnk[i][0];j;j=nxt[j][0])
{
fj=father[son[j][0]];
if (fi!=fj) add(fi,fj,1);
}
}
st=father[st];
for (i=1;i<=P;i++) who[i]=father[who[i]];
Spfa();
for (i=1;i<=P;i++) if (distz[who[i]]>ans) ans=distz[who[i]];
printf("%d\n",ans);
return 0;
}