玄关:MnZn 刚学 tarjan,一个 RE 剩下全 T 能过样例求条
查看原帖
玄关:MnZn 刚学 tarjan,一个 RE 剩下全 T 能过样例求条
1378591
Barewalk楼主2025/1/25 07:57

rt。

#include <iostream>
#define maxN 10100
#define maxM 100100
using namespace std;
int n, m, a[maxN], b[maxN], ans;
int max(int x, int y) {
	return x > y ? x : y;
}
int head[maxN][2], nxt[maxM][2], ver[maxM][2], cnt;
void addEdge(int x, int y, bool f) {
	nxt[++ cnt][f] = head[x][f]; head[x][f] = cnt; ver[cnt][f] = y;
}
bool vis[maxN];
int scc[maxN], tot;
int anc[maxN], top;
int dfn[maxN], low[maxN], idx;
void tarjan(int x) {
	low[x] = dfn[x] = ++ idx;
	anc[++ top] = x, vis[x] = true;
	for (int i = head[x][0]; i; i = nxt[i][0]) {
		int to = ver[i][0];
		if (!dfn[to]) {
			tarjan(to);
			low[x] = min(low[x], low[to]);
		}
		else if (vis[to]) {
			low[x] = min(low[x], dfn[to]);
		}
	}
	if (dfn[x] == low[x]) {
		int y; tot ++;
		do {
			y = anc[top --], vis[y] = false, scc[y] = tot, b[tot] += a[y];
		} while (x ^ y);
	}
}
int q[maxN], st = 1, ed;
int dist[maxN], inDegree[maxN];
void topSort() {
	for (int i = 1; i <= tot; ++ i)
		if (!inDegree[i]) {
			q[++ ed] = i; dist[i] = b[i];
		}
	while (st <= ed) {
		int x = q[st ++];
		ans = max(ans, dist[x]);
		for (int i = head[x][1]; i; i = nxt[i][1]) {
			int to = ver[i][1];
			dist[to] = max(dist[to], dist[x] + b[to]);
			inDegree[to] --;
			if (!inDegree[to]) q[++ ed] = to;
		}
	}
}
int main() {
	cin >> n >> m;
	for (int i = 1; i <= n; ++ i) cin >> a[i];
	for (int i = 1, u, v; i <= m; ++ i) {
		cin >> u >> v; addEdge(u, v, 0);
	}
	for (int i = 1; i <= n; ++ i)
		if (!dfn[i]) tarjan(i);
	cnt = 0;
	for (int x = 1; x <= n; ++ x)
		for (int i = head[x][0]; i; i = nxt[x][0]) {
			int to = ver[i][0];
			if (scc[x] == scc[to]) continue;
			addEdge(scc[x], scc[to], 1), inDegree[scc[to]] ++;
		}
	topSort();
	cout << ans << '\n';
	return 0;
}
2025/1/25 07:57
加载中...