Topic meaning:
A directed graph, some points can be used as end points, each point has a weight, each point and edge can be walked many times, and the weight of the point after the point has passed will not be counted in the score
Starting from a point, find a path that maximizes the score of this path and ends at one of the given points
output this path length
Ideas:
First tarjan shrinks the point
Then use spfa to run the longest road on the new map (beginning very naive thinking that it can be done with dfs
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring> 6 #include<algorithm> 7 #include<queue> 8 #include<vector> 9 #define ll long long 10 #define MAXN 500100 11 #define inf 2139062143 12 using namespace std; 13 inline int read() 14 { 15 int x=0,f=1;char ch=getchar(); 16 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 17 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 18 return x*f; 19 } 20 int n,m,fst[MAXN],nxt[MAXN],to[MAXN],cnt,val[MAXN],bar[MAXN],s,Fst[MAXN],Nxt[MAXN],To[MAXN]; 21 int ans,dfn[MAXN],low[MAXN],vis[MAXN],stp,top,st[MAXN],sum[MAXN],ok[MAXN],scc,bl[MAXN]; 22 int dis[MAXN],q[MAXN],head,tail; 23 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;} 24 void Add(int u,int v) {Nxt[++cnt]=Fst[u],Fst[u]=cnt,To[cnt]=v;} 25 void tarjan(int x) 26 { 27 dfn[x]=low[x]=++stp,vis[x]=1,st[++top]=x; 28 for(int i=fst[x];i;i=nxt[i]) 29 if(!dfn[to[i]]) {tarjan(to[i]);low[x]=min(low[x],low[to[i]]);} 30 else if(vis[to[i]]) low[x]=min(low[x],dfn[to[i]]); 31 if(low[x]==dfn[x]) 32 { 33 scc++;int now=0; 34 while(now!=x) 35 { 36 now=st[top--],vis[now]=0,sum[scc]+=val[now],bl[now]=scc; 37 if(bar[now]) ok[scc]=1; 38 } 39 } 40 } 41 void build() 42 { 43 cnt=0; 44 for(int i=1;i<=n;i++) 45 for(int j=fst[i];j;j=nxt[j]) 46 if(bl[i]!=bl[to[j]]) Add(bl[i],bl[to[j]]); 47 } 48 void spfa() 49 { 50 s=bl[s],head=tail=1,q[tail]=s,vis[s]=1; 51 while(head<=tail) 52 { 53 int x=q[head++];vis[x]=0; 54 for(int i=Fst[x];i;i=Nxt[i]) 55 if(dis[To[i]]<dis[x]+sum[To[i]]) 56 { 57 dis[To[i]]=dis[x]+sum[To[i]]; 58 if(!vis[To[i]]) {vis[To[i]]=1,q[++tail]=To[i];} 59 } 60 } 61 } 62 int main() 63 { 64 n=read(),m=read();int a,b,t; 65 while(m--) {a=read(),b=read();add(a,b);} 66 for(int i=1;i<=n;i++) val[i]=read(); 67 s=read(),t=read(); 68 for(int i=1;i<=t;i++) bar[read()]=1; 69 for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); 70 build();spfa(); 71 for(int i=1;i<=scc;i++) if(ok[i]) ans=max(ans,dis[i]); 72 printf("%d",ans+sum[s]); 73}