码迷,mamicode.com
首页 > 其他好文 > 详细

缩点+拓扑模板

时间:2021-01-04 10:30:49      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:namespace   tar   pop   height   blank   mem   www   empty   system   

技术图片
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#define ll long long
using namespace std;
const int N=5e5+100,M=5e5+100;
int n,m,dfn[N],low[N],dp[N];
bool ins[N],vis[N];
int dianquan[N],head[N],to[M],nxt[M],from[M];
int cnt=0,ind=0,tot=0;
int duiying[N],dianquan2[N],degree[N],head2[N],to2[M],nxt2[M];
void addedge(int u,int v)
{
    cnt++;
    to[cnt]=v;
    from[cnt]=u;
    nxt[cnt]=head[u];
    head[u]=cnt;
}
int cnt2=0;
void addedge2(int u,int v)
{
    cnt2++;
    to2[cnt2]=v;
    nxt2[cnt2]=head2[u];
    head2[u]=cnt2;
}
stack <int> s;
void tarjan(int u)
{
    ind++;
    low[u]=dfn[u]=ind;
    s.push(u);
    ins[u]=true;
    for(int p=head[u];p;p=nxt[p])
    {
        int v=to[p];
        if(!dfn[v])
        {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(ins[v]) low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u])
    {
        tot++;
        while(s.top()!=u)
        {
            ins[s.top()]=false;
            duiying[s.top()]=tot;
            dianquan2[tot]+=dianquan[s.top()];
            s.pop();
        }
        ins[u]=false;
        duiying[u]=tot;
        dianquan2[tot]+=dianquan[u];
        s.pop();
    }
}
queue <int> q;
int ret[N],rettot=0;
void tuopu()
{
    for(int i=1;i<=tot;i++)
        if(!degree[i]) q.push(i);
    while(!q.empty())
    {
        int u=q.front();
        ret[++rettot]=u,q.pop();
        for(int p=head2[u];p;p=nxt2[p])
        {
            int v=to2[p];
            degree[v]--;
            if(!degree[v]) q.push(v);
        }
    }
}
int main()
{
    memset(ins,false,sizeof(ins));
    memset(vis,false,sizeof(vis));
    cin>>n>>m;
    for(int i=1;i<=n;i++)   
        cin>>dianquan[i];
    for(int i=1;i<=m;i++)
    {
        int u,v;
        cin>>u>>v;
        addedge(u,v);
    }
    for(int i=1;i<=n;i++)
        if(!dfn[i]) tarjan(i);
    for(int i=1;i<=cnt;i++)
    {
        int u=duiying[from[i]],v=duiying[to[i]];
        if(u!=v)
        {
            degree[v]++;
            addedge2(u,v);
        }
    }
    tuopu();
    int ans=0;
    for(int u=1;u<=rettot;u++)
    {
        dp[u]=dianquan2[u];
        for(int p=head2[u];p;p=nxt2[p])
        {
            int v=to2[p];
            dp[u]=max(dp[u],dp[v]+dianquan2[u]);
        }
    }
    for(int i=1;i<=rettot;i++) ans=max(ans,dp[i]);
    cout<<ans;
    system("pause");
    return 0;
}
View Code

例题:P3387

 

缩点+拓扑模板

标签:namespace   tar   pop   height   blank   mem   www   empty   system   

原文地址:https://www.cnblogs.com/xqk-blog/p/14209448.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!