洛谷3387 缩点

//SPFA的缩点...可能会慢一点,,,但是真的很好理解啊!!

#include<iostream> #include<cstdio> #include<algorithm> #include<queue> #include<cstring> using namespace std; const int maxn=100010; bool vis[maxn]; int n,m,ans=0,cnt=0,tot=0,top=0,num=0; int u[maxn],v[maxn],head[maxn],low[maxn],dfn[maxn]; int dis[maxn],Dis[maxn],stack[maxn],po[maxn],a[maxn]; struct Edge{ int next,to; }cute[maxn]; void build(int x,int y) { cute[++tot].next=head[x]; cute[tot].to=y; head[x]=tot; } void tarjan(int x) { dfn[x]=low[x]=++num; stack[++top]=x; vis[x]=true; for(int i=head[x];i;i=cute[i].next) { int y=cute[i].to; if(vis[y]) low[x]=min(low[x],dfn[y]); else if(!dfn[y]) tarjan(y),low[x]=min(low[x],low[y]); } if(low[x]==dfn[x]) { vis[x]=false; cnt++; while(stack[top+1]!=x) { po[stack[top]]=cnt; vis[stack[top]]=false; Dis[cnt]+=a[stack[top]]; top--; } } } void Spfa(int x) { memset(vis,0,sizeof(vis)); memset(dis,0,sizeof(dis)); dis[x]=Dis[x]; queue<int> q; vis[x]=true; q.push(x); while(!q.empty()) { int u=q.front(); vis[u]=false; q.pop(); for(int i=head[u];i;i=cute[i].next) { int v=cute[i].to; if(dis[v]<dis[u]+Dis[v]) { dis[v]=dis[u]+Dis[v]; if(!vis[v]) { vis[v]=true; q.push(v); } } } } for(int i=1;i<=n;i++) ans=max(ans,dis[i]); } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=m;i++) { scanf("%d%d",&u[i],&v[i]); build(u[i],v[i]); } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); memset(head,0,sizeof(head)); memset(cute,0,sizeof(cute)); for(int i=1;i<=m;i++) if(po[u[i]]!=po[v[i]]) build(po[u[i]],po[v[i]]); for(int i=1;i<=n;i++) Spfa(i); printf("%d",ans); return 0; }

猜你喜欢

转载自www.cnblogs.com/Koiny/p/9879829.html