Looting plan

https://loj.ac/problem/10096

Title Description

  Someone ready to go from the start node No. 1 robbery, and a bar node to stop the robbery, the amount of money known each node ATM machine owned by seeking the largest amount of money robbery (can be repeated through road, robbed after ATM machine money).

Thinking

  We consider for a strongly connected component, he can certainly grab the finished strongly connected components all the money and reach any node, so we can reduce points. This point is the total weight amount of strongly connected components each point after point reduction. We DAG after shrinking for point, apparently can be converted into the right side of the right point to find the longest road in this picture. Here's longest road we can use spfa realize, here we avoid the use of topology, because we can only use topological sort to join the starting point, but can not join the other is 0 points, otherwise it will not reach the arrival point of comparison in the realization complex, the most direct short circuit is not much slower than the actual topology.

Code

#include <bits/stdc++.h>
using namespace std;
const int N=5e5+10,M=5e5+10;

struct Edge
{
    int x,y;
}e[M];

int v[N];
int nxt[M],to[M],head[N],w[N],tot;
void add_edge(int x,int y,int v)
{
    nxt[++tot]=head[x];
    head[x]=tot;
    to[tot]=y;
    w[tot]=v;
}

int read()
{
    int res=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){res=(res<<3)+(res<<1)+ch-'0';ch=getchar();}
    return res*w;
}

int dfn[N],low[N],st[N],co[N],sum[N],top,col,idx;
void tarjan(int u)
{
    dfn[u]=low[u]=++idx;
    st[++top]=u;
    for(int i=head[u];i;i=nxt[i])
    {
        int v=to[i];
        if(!dfn[v])
        {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(!co[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u])
    {
        co[u]=++col;
        sum[col]=v[u];
        while(st[top]!=u)
        {
            co[st[top]]=col;
            sum[col]+=v[st[top]];
            --top;
        }
        --top;
    }
}

int m;
void rebuild()
{
    tot=0;
    memset(head,0,sizeof(head));
    for(int i=1;i<=m;i++)
    {
        int u=co[e[i].x],v=co[e[i].y];
        if(u!=v)
            add_edge(u,v,sum[v]);
    }
}

int dis[N];
bool exist[N];
void spfa(int s)
{
    queue<int>q;
    dis[s]=sum[s];exist[s]=1;
    q.push(s);
    while(!q.empty())
    {
        int u=q.front();q.pop();
        exist[u]=0;
        for(int i=head[u];i;i=nxt[i])
        {
            int v=to[i];
            if(dis[v]<dis[u]+w[i])
            {
                dis[v]=dis[u]+w[i];
                if(!exist[v])
                {
                    exist[v]=1;
                    q.push(v);
                }
            }
        }
    }
}
int ed[N];
int main() 
{
    int n,s,p;
    n=read();m=read();
    for(int i=1;i<=m;i++)
    {
        int x=read(),y=read();
        add_edge(x,y,0);
        e[i].x=x;e[i].y=y;
    }
    for(int i=1;i<=n;i++)
        v[i]=read();
    s=read();p=read();
    for(int i=1;i<=p;i++)
        ed[i]=read();
    for(int i=1;i<=n;i++)
        if(!dfn[i])tarjan(i);
    rebuild();
    spfa(co[s]);
    int ans=0;
    for(int i=1;i<=p;i++)
        ans=max(ans,dis[co[ed[i]]]);
    printf("%d",ans);
}

 

Guess you like

Origin www.cnblogs.com/fangbozhen/p/11728898.html