求调玄关,样例过danshi爆零
查看原帖
求调玄关,样例过danshi爆零
1036180
ChampionCyan楼主2024/8/20 10:36
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e4 + 1, MAXM = 1e5 + 1;
int n, m, head[MAXN], cnt, a[MAXN];

struct Edge {
    int nex, to;
    Edge(int a = -1, int b = 0) : nex(a), to(b) {}
} edge[MAXM];

inline void add(int u, int v) {
    edge[cnt] = Edge(head[u], v);
    head[u] = cnt++;
}

inline void init() {
    for (int i = 1; i <= n; i++)
        head[i] = -1;
}

int dfn[MAXN], tot, low[MAXN], Stak[MAXN], Stop;
bool instack[MAXN];
int bcnt, belong[MAXN], bsum[MAXN];

void tarjan(int u) {
    dfn[u] = low[u] = ++tot;
    instack[u] = true;
    Stak[++Stop] = u;
    for (int i = head[u], v; ~i; i =  edge[i].nex) {
        v = edge[i].to;
        if (!dfn[v]) {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        } else if (instack[v])
            low[u] = min(low[u], dfn[v]);
    }
    if (dfn[u] == low[u]) {
        bcnt++;
        int p;
        do {
            p = Stak[Stop--];
            instack[p] = false;
            belong[p] = bcnt;
            bsum[bcnt] += a[p];
        } while (p != u);
    }
}

vector<int> to[MAXN];
int dp[MAXN];

int dfs(int u) {
    if (~dp[u])
        return dp[u];
    dp[u] = bsum[u];
    for (int v : to[u]) {
        dp[u] = max(dp[u], bsum[u] + dp[v]);
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    init();
    for (int i = 1, u, v; i <= m; i++) {
        scanf("%d%d", &u, &v);
        add(u, v);
    }for (int i = 1; i <= n; i++)
        if (!dfn[i])
            tarjan(i);
    for (int u = 1; u <= n; u++) {
        int bu = belong[u];
        for (int i = head[u], v; ~i; i = edge[i].nex) {
            v = edge[i].to;
            int bv = belong[v];
            if (bu == bv)
                continue;
            to[bu].push_back(bv);
        }
    }
    int ans = 0;
    for (int i = 1; i <= n; i++)
        ans = max(ans, dfs(i));
    printf("%d\n", n);
    return 0;
}
2024/8/20 10:36
加载中...