//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;
}
洛谷3387 缩点
猜你喜欢
转载自www.cnblogs.com/Koiny/p/9879829.html
今日推荐
周排行