60pts 萌新求助!
查看原帖
60pts 萌新求助!
215368
Easy_revenge楼主2021/4/20 21:50
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;

const int maxn = 1e5 + 10;

struct Edge {
	int u, v, nxt;
} edge[maxn], edge1[maxn]; int head[maxn], head1[maxn], tot, tot1;

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

inline void init1(int u, int v) {
	edge1[++tot1] = (Edge){ u, v, head1[u] }; head1[u] = tot1;
}

int n, m, w[maxn], ans;
int dfn[maxn], num, lw[maxn], st[maxn], tp, group[maxn], col, siz[maxn], d[maxn];
queue<int> q; int f[maxn];

void tarjan(int u) {
	dfn[u] = lw[u] = ++num;
	st[++tp] = u;
	for (int i = head[u]; i; i = edge[i].nxt) {
		int v = edge[i].v;
		if (!dfn[v]) {
			tarjan(v);
			lw[u] = min(lw[u], lw[v]);
		} else if (!group[v]) lw[u] = min(lw[u], dfn[v]);
	}
	if (dfn[u] == lw[u]) {
		group[u] = ++col; siz[col] += w[u];
		while (st[tp] != u) {
			group[st[tp]] = col; siz[col] += w[st[tp]];
			--tp;
		} --tp;
	}
}

void bfs() {
	for (int i = 1; i <= col; ++i) if (!d[i]) q.push(i), f[i] = siz[i];
	while (q.size()) {
		int u = q.front(); q.pop();
		for (int i = head1[u]; i; i = edge1[i].nxt) {
			int v = edge1[i].v;
			f[v] = max(f[v], f[u] + siz[v]); --d[v];
			if (!d[v]) q.push(v);
		}
	}
}

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) scanf("%d", &w[i]);
	for (int i = 1; i <= m; ++i) {
		int p1, p2; scanf("%d%d", &p1, &p2);
		init(p1, p2);
	}
	for (int i = 1; i <= n; ++i) if (!dfn[i]) tarjan(i);
	for (int i = 1; i <= tot; ++i) {
		if (group[edge[i].u] != group[edge[i].v]) init1(group[edge[i].u], group[edge[i].v]), ++d[edge[i].v];
	}
	bfs();
	for (int i = 1; i <= col; ++i) ans = max(ans, f[i]);
	printf("%d", ans);
	return 0;
}
2021/4/20 21:50
加载中...