国家一级爬山运动员h10今天获得了一张有着密密麻麻标记的地图,在好奇心的驱使下,他又踏上了去爬山的路。
对于爬山,h10有一个原则,那就是不走回头路,于是他把地图上的所有边都标记成了有向边。他决定从点S出发,每到达一个新的节点他就可以获得一定的成就值。同时h10又是一个很珍惜时间的运动员,他不希望这次爬山的成就值白白浪费,所以最后他一定要在一个存档点停下,保存自己的成就值。
请你计算出在此次爬山运动中h10能够得到的最大成就值。保证h10能走到存档点。
明明是一道大水题,结果题目的意思没有讲清楚。
题意是每条边可以走很多次,那么明显一个强连通分量可以缩成一个点了。
用tarjan缩完点之后,再用spfa找最长路就好了。
所以要打非递归般的tarjan。
#include
#include
#include
#include
#include
#include
#define fo(i,a,b) for(i=a;i<=b;i++)
#define rep(i,a) for(i=first[a];i;i=next[i])
#define rep1(i,a) for(i=first1[a];i;i=next1[i])
using namespace std;
const int maxn=500007;
typedef long long ll;
int i,j,k,l,t,n,m,S,q;
int first[maxn],next[maxn],last[maxn],num;
int first1[maxn],next1[maxn],last1[maxn],num1,b[maxn],nn;
int data[maxn];
ll d[maxn],ans,a[maxn],zhi[maxn];
int low[maxn],dfn[maxn],dfsx;
bool bz[maxn],az[maxn];
int st[maxn],hhh,e[maxn],g[maxn];
stack<int> zh;
void add(int x,int y){
last[++num]=y,next[num]=first[x],first[x]=num;
}
void add1(int x,int y){
last1[++num1]=y,next1[num1]=first1[x],first1[x]=num1;
}
void tarjan(int x)
{
int i;
zh.push(x);
dfn[x]=low[x]=++dfsx;
st[++st[0]]=x;
az[x]=1;
while(!zh.empty())
{
int t=zh.top();
rep(i,t)
{
if(!dfn[last[i]]){
dfn[last[i]]=low[last[i]]=++dfsx;
st[++st[0]]=last[i];az[last[i]]=1;
zh.push(last[i]);
break;
}
}
if(t==zh.top())
{
rep(i,t)
{
if(dfn[last[i]]>dfn[t])low[t]=min(low[t],low[last[i]]);
else if(az[last[i]])low[t]=min(low[t],dfn[last[i]]);
}
if(dfn[t]==low[t])
{
++hhh;
int j;
do
{
j=st[st[0]--];
az[j]=0;
b[j]=hhh;
}while(j!=t);
}
zh.pop();
}
}
}
void spfa(int x){
int head=0,tail=1,now,i,j;
data[1]=x,d[x]=zhi[x];bz[x]=1;
while(headif(d[last1[i]]if(!bz[last1[i]]){
bz[last1[i]]=1;
data[++tail]=last1[i];
}
}
}
bz[now]=0;
}
}
int main(){
// freopen("fan.in","r",stdin);
scanf("%d%d",&n,&m);
fo(i,1,m){
scanf("%d%d",&k,&l);
e[i]=k,g[i]=l;
add(k,l);
}
fo(i,1,n)scanf("%d",&a[i]);
fo(i,1,n){
if(!dfn[i]){
tarjan(i);
}
}
fo(i,1,n){
zhi[b[i]]+=a[i];
}
fo(i,1,m){
if(b[e[i]]==b[g[i]])continue;
add1(b[e[i]],b[g[i]]);
}
scanf("%d%d",&S,&q);
memset(bz,0,sizeof(bz));
spfa(b[S]);
fo(i,1,q){
scanf("%d",&k);
ans=max(ans,d[b[k]]);
}
printf("%lld",ans);
}