逆天数据&警示后人
查看原帖
逆天数据&警示后人
704668
WZRYWZWY楼主2024/11/20 21:43
#include <bits/stdc++.h> // 借鉴了蓝书和题解 
using namespace std;

const int N = 1e5 + 5, M = 1e6 + 5;

int dfn[N], low[N], sta[N], c[N]; // c[x] x所在强联通分量的编号 
bool vis[N];

vector <int> scc[N], e[N], e2[N]; // 编号为i的强联通分量的所有点

int n, m, _dfn, top, cnt;
int a[N], a2[N];

void tarjan(int u) {
	dfn[u] = low[u] = ++ _dfn;
	sta[++top] = u; 
	vis[u] = 1;
	
	for (int v : e[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 (low[u] == dfn[u]) {
		cnt ++;
		int v;
		do {
			v = sta[top --];
			vis[v] = 0;
			c[v] = cnt;
			a2[cnt] += a[v];
			scc[cnt].push_back(v);
		} while (v != u);
	}
}
 
int in[N], f[N];
queue <int> q;

void topo() {
	while (q.size()) {
		int u = q.front();
		q.pop();
		for (int v : e2[u]) {
			f[v] = max(f[v], f[u] + a2[v]);
			if (--in[v] == 0) {
				q.push(v);
			}
		}
	}
}

int main() {
	cin.tie(0); ios::sync_with_stdio(0);
	int n, m; cin >> n >> m;
	for (int i = 1; i <= n; i++) cin >> a[i];
	while (m--) {
		int u, v; cin >> u >> v;
		e[u].push_back(v);
	}
	
	for (int i = 1; i <= n; i++)
		if (!dfn[i]) tarjan(i);
	
	for (int u = 1; u <= n; u++)
		for (int v : e[u]) {
			if (c[u] == c[v]) continue;
			e2[c[u]].push_back(c[v]);
			in[c[v]] ++;
		}
	
	for (int i = 1; i <= cnt; i++) if (!in[i]) q.push(i), f[i] = a2[i];
	
	topo();
	int ans = 0;
	for (int i = 1; i <= cnt; i++) ans = max(ans, f[i]);
	cout << ans;
	return 0;
}

第 70 行写成 in[v] ++; 都能有 60 分……

新图的东西不要和旧图搞混了,尤其是缩点后的节点和新边

2024/11/20 21:43
加载中...