萌新样例不过求调
查看原帖
萌新样例不过求调
1222486
TangyixiaoQAQ楼主2024/7/15 14:12
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;
struct Edge {
    int to, nxt, from;
} edge[N];
vector<int> edge_new[N];
vector<int> re[N];
stack<int> st;
bool vis[N];
int ANSWER, n, m, tot, totq, mm, w[N], f[N], ans[N], low[N], dfn[N], rt[N], dis[N], deg[N], heads[N], cnt;
namespace Tarjan {
void Tarjan_Shrink_point(int u) {
    dfn[u] = low[u] = ++cnt;
    vis[u] = true;
    st.push(u);
    for (int i = heads[u]; i != -1; i = edge[i].nxt) {
        if (!dfn[edge[i].to]) {
            Tarjan_Shrink_point(edge[i].to);
            low[u] = min(low[u], low[edge[i].to]);
        } else {
            if (vis[edge[i].to]) {
                low[u] = min(low[u], dfn[edge[i].to]);
            }
        }
    }
    if (low[u] == dfn[u]) {
        cnt++;
        do {
            rt[st.top()] = cnt;
            vis[st.top()] = false;
            dis[cnt] += w[st.top()];
            st.pop();
        } while (st.top() != u);
    }
    return;
}
}  // namespace Tarjan
using namespace Tarjan;
int topo() {
    queue<int> q;
    for (int i = 1; i <= cnt; i++) {
        if (!deg[i]) {
            q.push(i);
        }
    }
    while (!q.empty()) {
        int u = q.front();
        ans[++totq] = u;
        q.pop();
        for (int i = 1; i <= edge_new[u].size(); i++) {
            if (!(--deg[edge_new[u][i - 1]])) {
                q.push(edge_new[u][i - 1]);
            }
        }
    }
    for (int i = 1; i <= cnt; i++) {
        f[ans[i]] = dis[ans[i]];
        for (int j = 1; j <= re[ans[i]].size(); j++) {
            f[ans[i]] = max(f[ans[i]], f[re[ans[i]][j - 1]] + dis[ans[i]]);
        }
    }
    for (int i = 1; i <= cnt; i++) {
        ANSWER = max(ANSWER, f[i]);
    }
    return ANSWER;
}
signed main() {
    memset(heads, -1, sizeof(heads));
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &w[i]);
    }
    for (int i = 1; i <= m; i++) {
        int u, v;
        scanf("%d%d", &u, &v);
        edge[++mm].nxt = heads[u];
        edge[mm].from = u;
        edge[mm].to = v;
        heads[u] = mm;
    }
    for (int i = 1; i <= n; i++) {
        if (!dfn[i]) {
            Tarjan_Shrink_point(i);
        }
    }
    for (int i = 1; i <= mm; i++) {
        if (vis[edge[i].from] != vis[edge[i].to]) {
            edge_new[rt[edge[i].from]].push_back(rt[edge[i].to]);
            re[rt[edge[i].to]].push_back(rt[edge[i].from]);
            deg[rt[edge[i].to]]++;
        }
    }
    printf("%d\n", topo());
    return 0;
}

感觉和第二篇题解写的差不多啊

2024/7/15 14:12
加载中...