Luogu3387 缩点

缩点+DAG上DP

缩完点跑一遍拓扑,无后效性。真你妈神烦,调不过去。

艹调了一个小时就因为一个入度加错点了。我真傻叉。

CODE:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
#define maxn 10001
#define maxm 100001
int n, m, low[maxn], dfn[maxn], scc[maxn];
int tot, col, ans, top, cnt;
struct edge{
    int nxt, to;
}e[maxm];
int st[maxn], dis[maxn], w[maxn], head[maxn], val[maxn], ind[maxn];
inline int read(){
    int f=1, x=0;
    char ch=getchar();
    for(;!isdigit(ch); ch=getchar()) if(ch=='-') f=-1;
    for(; isdigit(ch); ch=getchar()) x=x*10+ch-48;
    return x*f;
}
void add(int u, int v){
    e[++tot].nxt=head[u];
    e[tot].to=v;
    head[u]=tot;
}
void tarjan(int u){
    dfn[u]=low[u]=++cnt;
    st[++top]=u;
    for(int i=head[u]; i; i=e[i].nxt){
        int v=e[i].to;
        if(!dfn[v]){
            tarjan(v);
            low[u]=min(low[u], low[v]);
        }
        else if(!scc[v])
            low[u]=min(low[u], dfn[v]);
    }
    if(low[u]==dfn[u]){
        scc[u]=++col;
        w[col]+=val[u];
        while(st[top]!=u){
            scc[st[top]]=col;
            w[col]+=val[st[top--]];
        }
        top--;
    }
}
void topo(){
    queue<int>q;
    for(int i=1; i<=col; i++)
        if(!ind[i]){
            q.push(i);
            dis[i]=w[i];
        }
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=head[u]; i; i=e[i].nxt){
            int v=e[i].to;
            dis[v]=max(dis[v], dis[u]+w[v]);
            ind[v]--;
            if(!ind[v]) q.push(v);
        }
    }
    ans=0;
    for(int i=1; i<=n; i++)
        ans=max(ans, dis[i]);
}
int x[maxm], y[maxm];
int main(){
    n=read(), m=read();
    for(int i=1; i<=n; i++) val[i]=read();
    for(int i=1; i<=m; i++){
        x[i]=read(), y[i]=read();
        add(x[i], y[i]);
    }
    for(int i=1; i<=n; i++)
        if(!dfn[i])tarjan(i);
    memset(e, 0, sizeof(e));
    memset(head, 0, sizeof(head));
    for(int i=1; i<=m; i++)
        if(scc[x[i]]!=scc[y[i]])
            add(scc[x[i]], scc[y[i]]), ind[scc[y[i]]]++;
    topo();
    printf("%d", ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/pushinl/p/9911914.html