60pts求调
查看原帖
60pts求调
764666
LostKeyToReach楼主2024/8/23 12:24
#include <iostream>
#include <stack>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
using i64 = long long;
const int N = 1e4 + 5, M = 1e5 + 4;
int n, m, low[N], dfn[N], scc[N], tot = 0, val[N], scctot;
i64 deg[N], siz[N], dis[N];
bool vis[N];
stack <int> s;
queue <int> q;
pair <int, int> edges[N * 10];
vector <int> adj[N], new_adj[N];
void spfa(int u) {
	while (!q.empty()) q.pop();
	q.push(u), vis[u] = 1;
	dis[u] = siz[u];
	while (!q.empty()) {
		int x = q.front(); q.pop();
		vis[x] = 0;
		for (auto v : new_adj[x]) {
			if (dis[v] < dis[u] + siz[v]) {
				dis[v] = dis[u] + siz[v];
				if (!vis[v]) {
					vis[v] = 1, q.push(v);
				}
			}
		}
	}
}
void tarjan(int u) {
	dfn[u] = low[u] = ++tot;
	s.push(u), vis[u] = 1;
	for (auto v : adj[u]) {
		if (!dfn[v]) {
			tarjan(v);
			low[u] = min(low[u], low[v]);
		} else if (vis[v]) {
			low[u] = min(low[u], dfn[v]);
		}
	}
	if (dfn[u] == low[u]) {
		++scctot;
		int v;
		do {
			v = s.top();
			vis[v] = 0;
			s.pop();
			scc[v] = scctot;
		} while (v != u);
	}
}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		cin >> val[i];
	}
	for (int i = 1; i <= m; i++) {
		int u, v;
		cin >> u >> v;
		edges[i] = {u, v};
		adj[u].emplace_back(v);
	}
	for (int i = 1; i <= n; i++) {
		if (!dfn[i]) {
			tarjan(i);
		}
	}
	for (int i = 1; i <= m; i++) {
		int scc_u = scc[edges[i].first];
		int scc_v = scc[edges[i].second];
		if (scc_u != scc_v) {
			new_adj[scc_u].emplace_back(scc_v);
		}
	}
	for (int i = 1; i <= n; i++) {
		siz[scc[i]] += 1ll * val[i];
	}
	memset(vis, 0, sizeof vis);
	memset(dis, -1, sizeof dis);
	for (int i = 1; i <= scctot; i++) {
		if (dis[i] == -1) {
			spfa(i);
		}
	}
	cout << *max_element(dis + 1, dis + scctot + 1);
}
2024/8/23 12:24
加载中...