#Tarjan,SPFA#洛谷 3627 [APIO2009] 抢掠计划

题目


分析

首先重复走,钱只会计算一次,而且与路程长度无关,考虑有向图缩点,然后跑最长路,这里吧边权取反跑最短路,然后在酒吧结束也就是求\(-dis[col_x]\)的最大值,\(col_x\)也就是就把缩点后的编号


代码

#include <cstdio>
#include <cctype>
#include <queue>
#define rr register
using namespace std;
const int N=500011; struct node{int y,next;}e[N];
struct Node{int y,w,next;}E[N]; bool v[N]; queue<int>q;
int ls[N],hs[N],dis[N],dfn[N],low[N],sum[N],col[N],a[N].cnt,top,sta[N],ans,n,m,k,num;
inline signed iut(){
    rr int ans=0; rr char c=getchar();
    while (!isdigit(c)) c=getchar();
    while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    return ans;
}
inline signed min(int a,int b){return a<b?a:b;}
inline signed max(int a,int b){return a>b?a:b;}
inline void add(int x,int y,int w){E[++k]=(Node){y,w,hs[x]},hs[x]=k;}
inline void tarjan(int x){
    dfn[x]=low[x]=++num,sta[++top]=x,v[x]=1;
    for (rr int i=ls[x];i;i=e[i].next)
    if (!dfn[e[i].y]){
        tarjan(e[i].y);
        low[x]=min(low[x],low[e[i].y]);
    }else if (v[e[i].y])
        low[x]=min(low[x],dfn[e[i].y]);
    if (dfn[x]==low[x]){
        ++cnt; rr int y;
        do{
            y=sta[top--],v[y]=0;
            col[y]=cnt,sum[cnt]+=a[y];
        }while (x!=y);
    }
}
signed main(){
    n=iut(); m=iut();
    for (rr int i=1;i<=m;++i){
        rr int x=iut(),y=iut();
        e[i]=(node){y,ls[x]},ls[x]=i;
    }
    for (rr int i=1;i<=n;++i) a[i]=iut(),dis[i]=2e9+7;
    for (rr int i=1;i<=n;++i) if (!dfn[i]) tarjan(i);
    for (rr int i=1;i<=n;++i)
    for (rr int j=ls[i];j;j=e[j].next)
    if (col[i]!=col[e[j].y]) add(col[i],col[e[j].y],-sum[col[e[j].y]]);
    rr int u=col[iut()]; dis[u]=-sum[u],v[u]=1,q.push(u);
    while (q.size()){
        rr int x=q.front(); q.pop();
        for (rr int i=hs[x];i;i=E[i].next)
        if (dis[E[i].y]>dis[x]+E[i].w){
            dis[E[i].y]=dis[x]+E[i].w;
            if (!v[E[i].y]) v[E[i].y]=1,q.push(E[i].y);
        }
        v[x]=0;
    }
    for (rr int Q=iut();Q;--Q) ans=max(ans,-dis[col[iut()]]);
    return !printf("%d",ans);
}
posted @ 2020-01-16 10:32  lemondinosaur  阅读(91)  评论(0编辑  收藏  举报