【APIO2009】抢掠计划(scc+spfa)
拿到题目首先想到:一个强连通分量里的点都可以互相走到
所以我们先缩点
缩完点后只需用spfa跑一遍最长路 最后再统计一下有哪些含有酒吧的强连通分量 取最大值
就是代码有点冗长
#include<bits/stdc++.h> #define N 500005 #define INF 0x7fffffff using namespace std; struct Edge { int to,next; }edge[N]; int n,m,first[N],tot,val[N]; int s,p; bool is_bar[N],have_bar[N]; inline void addedge(int x,int y) { tot++; edge[tot].to=y; edge[tot].next=first[x]; first[x]=tot; } int dfn[N],low[N],sign,cnt,belong[N],sum[N]; bool insta[N]; stack <int> sta; void dfs(int now) { dfn[now]=low[now]=++sign; sta.push(now); insta[now]=true; for(int u=first[now];u;u=edge[u].next) { int vis=edge[u].to; if(!dfn[vis]) { dfs(vis); low[now]=min(low[now],low[vis]); } else if(insta[vis]) low[now]=min(low[now],dfn[vis]); } if(low[now]==dfn[now]) { int temp; cnt++; do { temp=sta.top(); if(is_bar[temp]) have_bar[cnt]=true; sum[cnt]+=val[temp]; insta[temp]=false; belong[temp]=cnt; sta.pop(); }while(temp!=now); } } struct SCC { int to,next,val; }edge_spfa[N]; int head[N],dis[N],ans; inline void addedge2(int x,int y,int z) { tot++; edge_spfa[tot].to=y; edge_spfa[tot].next=head[x]; edge_spfa[tot].val=z; head[x]=tot; } queue <int> q; bool inque[N]; void spfa(int s) { q.push(s); inque[s]=true; for(int i=1;i<=cnt;i++) dis[i]=-INF; dis[s]=sum[s]; while(!q.empty()) { int now=q.front(); q.pop(); inque[now]=false; for(int u=head[now];u;u=edge_spfa[u].next) { int vis=edge_spfa[u].to; if(dis[now]+edge_spfa[u].val>dis[vis]) { dis[vis]=dis[now]+edge_spfa[u].val; if(!inque[vis]) { q.push(vis); } } } } for(int i=1;i<=cnt;i++) if(have_bar[i]) ans=max(ans,dis[i]); } int main() { ios::sync_with_stdio(false); cin.tie(NULL);cout.tie(NULL); cin>>n>>m; for(int i=1;i<=m;i++) { int x,y; cin>>x>>y; addedge(x,y); } for(int i=1;i<=n;i++) cin>>val[i]; cin>>s>>p; for(int i=1;i<=p;i++) { int x; cin>>x; is_bar[x]=true; } for(int i=1;i<=n;i++) if(!dfn[i]) dfs(i); tot=0; for(int i=1;i<=n;i++) { for(int u=first[i];u;u=edge[u].next) { int vis=edge[u].to; if(belong[vis]!=belong[i]) { addedge2(belong[i],belong[vis],sum[belong[vis]]); } } } spfa(belong[s]); cout<<ans; return 0; }
QQ40523591~欢迎一起学习交流~