题目大意:方老师没钱买拖鞋了所以决定去抢银行,城市可以看做n个路口和m个道路,城市从1开始编号。每个路口上有一个ATM
机器里面有钱
m条单向道路连接城市,方老师从他的据点p出发,开始一路抢最后在一个网吧结束自己的旅程。城市里一共有k个网吧(网吧都在路口上)。
代码实现:
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
#include<iostream>
#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define MEM(a) (memset((a),0,sizeof(a)))
#define MEME(a) (memset((a),-1,sizeof(a)))
#define MEMX(a) (memset((a),0x3f,sizeof(a)))
using namespace std;
const int N=100005;
int dfn[N],low[N],st[N],belong[N],road[N],dp[N],in[N],s_value[N],value[N],bcnt,top,s_top,tim,n,m,p,k,max_value;
bool inst[N],vis[N],flag;
vector<int> v[N];
struct Edge{
int to;
Edge *next;
}*head[N],e[N*3];
void Addedege(int from,int to){
Edge *p=&e[top++];
p->to=to;
p->next=head[from];
head[from]=p;
}
void Tarjan(int u){
dfn[u]=low[u]=++tim;
st[++s_top]=u;
inst[u]=1;
int v;
for(Edge *p=head[u];p;p=p->next){
v=p->to;
if(!dfn[v]){
Tarjan(v);
if(low[v]<low[u]) low[u]=low[v];
}else if(inst[v]&&dfn[v]<low[u]) low[u]=dfn[v];
}
if(dfn[u]==low[u]){
bcnt++;
do{
v=st[s_top--];
inst[v]=0;
belong[v]=bcnt;
s_value[bcnt]+=value[v];
}while(u!=v);
}
}
void dfs(int u,int sum){
sum+=s_value[u];
for(int i=0;i<k;++i)
if(u==belong[road[i]]){
max_value=Max(max_value,sum);
break;
}
for(int i=0;i<v[u].size();++i) dfs(v[u][i],sum);
}
int main(){
int p1,p2;
while(~scanf("%d%d",&n,&m)){
MEM(head),MEM(dfn),MEM(low),MEM(inst),MEM(s_value),MEM(in),MEM(vis),MEM(dp);
bcnt=top=s_top=tim=max_value=0;
for(int i=1;i<=n;++i) v[i].clear();
while(m--){
scanf("%d%d",&p1,&p2);
Addedege(p1,p2);
}
for(int i=1;i<=n;++i) scanf("%d",&value[i]);
scanf("%d",&p);
scanf("%d",&k);
for(int i=0;i<k;++i) scanf("%d",&road[i]);
for(int i=1;i<=n;++i) if(!dfn[i]) Tarjan(i);
for(int i=1;i<=n;++i)
for(Edge *p=head[i];p;p=p->next)
if(belong[i]!=belong[p->to]) v[belong[i]].push_back(belong[p->to]);
dfs(belong[p],0);
printf("%d\n",max_value);
}
}