有一个40pts,但确信sta写对了个萌新
查看原帖
有一个40pts,但确信sta写对了个萌新
651786
yyc_楼主2022/11/25 17:07
#include<bits/stdc++.h>
using namespace std;
using cint = const int&;
const int maxn = 1e5 + 10;
struct {
	int nxt, v;
}edge[maxn], tpe[maxn];
int head[maxn], tph[maxn], cnt, tpcnt, in[maxn];
inline void addedge(cint u, cint v) {
	edge[++cnt] = { head[u],v };
	head[u] = cnt;
}
inline void addtpe(cint u, cint v) {
	tpe[++tpcnt] = { tph[u],v };
	tph[u] = tpcnt;
	++in[v];
}
stack<int> sta;
int n, m, u, v, dfn[maxn], scc[maxn], low[maxn], dfns, val[maxn];
void tarjan(cint u) {
	dfn[u] = low[u] = ++dfns;
	sta.push(u);
	for (auto i = head[u]; i; i = edge[i].nxt) {
		const int v = edge[i].v;
		if (!dfn[v]) {
			tarjan(v);
			low[u] = min(low[v], low[u]);
		}
		else if (!scc[v]) low[u] = min(dfn[v], low[u]);
	}
	if (low[u] == dfn[u]) {
		scc[u] = u;
		while (sta.top() != u) {
			scc[sta.top()] = u;
			val[u] += val[sta.top()];
			sta.pop();
		}
		sta.pop();
	}
}

inline void rebuild() {
	for (int i = 1; i <= n; ++i)
		for (int j = head[i]; j; j = edge[j].nxt)
			if (scc[i] != scc[j])
				addtpe(scc[i], scc[j]);
}
int p[maxn];
inline void toposort() {
	queue<int> q;
	for (int i = 1; i <= n; ++i)
		if (!in[i] && scc[i] == i)
			q.push(i), p[i] = val[i];
	while (!q.empty()) {
		const int u = q.front();
		q.pop();
		for (int i = tph[u]; i; i = tpe[i].nxt) {
			const int v = tpe[i].v;
			val[v] = max(val[v], val[u] + p[v]);
			if (--in[v] == 0) q.push(v);
		}
	}
}
int main() {
	cin >> n >> m;
	for (int i = 1; i <= n; ++i) cin >> val[i];
	for (int i = 1; i <= m; ++i) {
		cin >> u >> v;
		addedge(u, v);
	}
	for (int i = 1; i <= n; ++i) if (!dfn[i]) tarjan(i);
	rebuild();
	toposort();
	int maxv = 0;
	for (int i = 1; i <= n; ++i) maxv = max(maxv, val[i]);
	cout << maxv;
}

WA, 40pts

2022/11/25 17:07
加载中...