WA#1、#3、#4、#5、#7、#求调
查看原帖
WA#1、#3、#4、#5、#7、#求调
500803
zzxzzxCCC楼主2024/8/14 22:21

tarjan之后不就已经就是拓扑图了吗

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 1e5 + 1e4, maxm = 1e5 + 1e4;
int timestamp, in_stk[maxn], dfn[maxn], low[maxn];
int scc_cnt, id[maxn], sum[maxn], f[maxn];
int idx, h[maxn], ne[maxm], e[maxm];
int stk[maxn], top;
int n, m, val[maxn], x[maxm], y[maxm], ans;
void add(int x, int y){
    e[++ idx] = y, ne[idx] = h[x], h[x] = idx;
}
void tarjan(int u){
    dfn[u] = low[u] = ++ timestamp;
    stk[++ top] = u, in_stk[u] = true;
    for(int i = h[u]; ~i; i = ne[i]){
        int j = e[i];
        if(!dfn[j]){
            tarjan(j);
            low[u] = min(low[u], low[j]);
        }
        else if(in_stk[j])
            low[u] = min(low[u], low[j]);
    }
    if(dfn[u] == low[u]){
        ++ scc_cnt;
        int y;
        do{
            y = stk[top --];
            in_stk[y] = false;
            sum[scc_cnt] += val[stk[y]];
            id[y] = scc_cnt;
        }while(y != u);
    }
}
void dfs(int x){
    if(f[x]) return ;
    f[x] = sum[x];
    int maxsum = 0;
    for (int i = h[x]; ~i; i = ne[i]){
        if(!f[e[i]]) dfs(e[i]);
        maxsum = max(maxsum, f[e[i]]);
    }
    f[x] += maxsum;
}
int main(){
    scanf("%d%d", &n, &m);
    memset(h, -1, sizeof(h));
    for (int i = 1; i <= n; i ++) scanf("%d", &val[i]);
    for (int i = 1; i <= m; i ++){
        scanf("%d%d", &x[i], &y[i]);
        add(x[i], y[i]);
    }
    for (int i = 1; i <= n; i ++) if(!dfn[i]) tarjan(i);
    memset(h, -1, sizeof(h));
    memset(ne, 0, sizeof(ne));
    memset(e, 0, sizeof(e));
    idx=0;
    for (int i = 1; i <= m; i ++)
        if(id[x[i]] != id[y[i]])
            add(id[x[i]], id[y[i]]);
    for (int i = 1; i <= scc_cnt; i ++)
        if(!f[i]){
            dfs(i);
            ans = max(ans, f[i]);
        }
    printf("%d", ans);
    return 0;
}
2024/8/14 22:21
加载中...