不是Tarjan或Kosaraju,是这位dalao的
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int vis[maxn],fa[maxn],dq[maxn],ru[maxn],sdq[maxn],dp[maxn];//fa:并查集的dq:点权sdq:缩点后的点权
vector<int> e[maxn],re[maxn];//e:原图re:缩点后的图
int n,m,x,y;
int cha(int x)//并查集
{
if(x==fa[x])return x;
return fa[x]=cha(fa[x]);
}
void cat(int u)//缩点过程
{
for(int i=0;i<e[u].size();i++)
{
int v=e[u][i];
if(!vis[v])
{
vis[v]=vis[u]+1;
cat(v);
}
int fu=cha(u),fv=cha(v);
if(vis[fv]>0)
{
if(vis[fu]<vis[fv])fa[fv]=fu;
else fa[fu]=fv;
}
}
vis[u]=-1;
}
int main()
{
memset(vis,0,sizeof(vis));
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>dq[i];
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=m;i++)
{
cin>>x>>y;
e[x].push_back(y);
e[y].push_back(x);
}
for(int i=1;i<=n;i++)
{
if(!vis[i])
{
vis[i]=1;
cat(i);
}
}
memset(ru,0,sizeof(ru));
for(int i=1;i<=n;i++)
{
for(int j=0;j<e[i].size();j++)
{
int u=i,v=e[u][j];
if(cha(u)!=cha(v))
{
ru[v]++;
re[u].push_back(v);
re[v].push_back(u);
}
}
}
memset(sdq,0,sizeof(sdq));
for(int i=1;i<=n;i++)
{
sdq[cha(i)]+=dq[i];
}
queue<int> q;
for(int i=1;i<=n;i++)
{
if(i==fa(i)&&!ru[i])
{
dp[i]=sdq[i];
q.push(i);
}
}
int ans=-0x3f3f3f3f;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=0;i<re[u].size();i++)
{
int v=re[u][i];
dp[v]=max(dp[v],dp[u]+dp[v]);
if(--ru[v]==0)q.push(v);
}
ans=max(ans,dp[u]);
}
cout<<ans;
return 0;
}