很久没更博客了qwq
https://www.lydsy.com/JudgeOnline/problem.php?id=1179
似乎不是很难,点可以重复走,但只算一次,这么办?考虑把点缩起来,显然这样就可以解决了。
之后跑跑spfa就行了
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 using namespace std; 5 const int N=500000+5; 6 int v[N],nxt[N],first[N],cnt; 7 int bl[N],b[N],w[N]; 8 int low[N],dfn[N],tim; 9 int st[N],top,sz; 10 int bar[N],s,n,m,p; 11 int aa[N],bb[N]; 12 bool vis[N]; 13 14 void read(int &x){ 15 x=0;int f=1;char c=getchar(); 16 while(c<'0'||c>'9'){if(c=='-')f=-f;c=getchar();} 17 while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c-'0');c=getchar();} 18 x*=f; 19 } 20 21 void add(int a,int b){ 22 v[++cnt]=b; 23 nxt[cnt]=first[a]; 24 first[a]=cnt; 25 } 26 27 void tarjan(int x){ 28 dfn[x]=low[x]=++tim; 29 st[++top]=x; 30 vis[x]=1; 31 for(int i=first[x];i;i=nxt[i]){ 32 if(!dfn[v[i]]){ 33 tarjan(v[i]); 34 low[x]=min(low[x],low[v[i]]); 35 } 36 else if(vis[v[i]]) low[x]=min(low[x],dfn[v[i]]); 37 } 38 if(low[x]==dfn[x]){ 39 bl[x]=++sz; 40 b[sz]=w[x]; 41 vis[x]=0; 42 while(st[top]!=x){ 43 vis[st[top]]=0; 44 b[sz]+=w[st[top]]; 45 bl[st[top--]]=sz; 46 } 47 --top; 48 } 49 } 50 51 void rebuild(){ 52 memset(v,0,sizeof(v)); 53 memset(nxt,0,sizeof(nxt)); 54 memset(first,0,sizeof(first)); 55 cnt=0; 56 for(int i=1;i<=m;i++) if(bl[aa[i]]!=bl[bb[i]]) add(bl[aa[i]],bl[bb[i]]); 57 } 58 59 int dis[N],q[N*10]; 60 int inq[N]; 61 void spfa(int s){ 62 for(int i=1;i<=sz;i++) dis[i]=b[i]; 63 inq[s]=1;q[1]=s; 64 int head=1,tail=2; 65 while(head!=tail){ 66 int x=q[head++];inq[x]=0; 67 if(head==N*10) head=1; 68 for(int i=first[x];i;i=nxt[i]) 69 if(dis[x]+b[v[i]]>dis[v[i]]){ 70 dis[v[i]]=dis[x]+b[v[i]]; 71 if(!inq[v[i]]){ 72 q[tail++]=v[i];inq[v[i]]=1; 73 if(tail==N*10) tail=1; 74 } 75 } 76 } 77 } 78 79 int main(){ 80 read(n);read(m); 81 for(int i=1;i<=m;i++){ 82 read(aa[i]);read(bb[i]); 83 add(aa[i],bb[i]); 84 } 85 for(int i=1;i<=n;i++) read(w[i]); 86 read(s);read(p); 87 for(int i=1;i<=p;i++) read(bar[i]); 88 for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); 89 rebuild();spfa(bl[s]); 90 int ans=0; 91 for(int i=1;i<=p;i++) ans=max(ans,dis[bl[bar[i]]]); 92 printf("%d",ans); 93 return 0; 94 }