求调,玄关
查看原帖
求调,玄关
700558
williamwei楼主2024/6/26 09:40
#include <iostream>
#include <map>
#include <vector>
#include <tuple>
#include <algorithm>
using namespace std;
const int maxn = 3e6 + 10;
const int dx[] = {1, 1, 1, 0, 0, -1, -1, -1};
const int dy[] = {1, 0, -1, 1, -1, 1, 0, -1};
int n, m, k, tot, top, cnt, head, tail, q[maxn], f[maxn], low[maxn], dfn[maxn], stk[maxn], deg[maxn], scc[maxn];
bool val[maxn], instack[maxn];
vector<int> e[maxn], g[maxn];
map<pair<int, int>, int> id;
void tarjan(int u) {
	dfn[u] = low[u] = ++tot; instack[u] = true; stk[++top] = u;
	for (int v : e[u])
		if (!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
		else if (instack[v]) low[u] = min(low[u], dfn[v]);
	if (dfn[u] == low[u]) {
		scc[u] = ++cnt; val[cnt] = u <= k;
		while (stk[top] != u)
			val[scc[stk[top]] = cnt] += stk[top] <= k, instack[stk[top--]] = false;
		instack[stk[top--]] = false;
	}
}
int main() {
	ios::sync_with_stdio(false);
	cin >> k >> n >> m;
	vector<tuple<int, int, int> > G(k);
	for (auto& [x, y, t] : G)
		cin >> x >> y >> t, id[{x, y}] = ++tot,
		e[k + x].push_back(tot), e[k + n + y].push_back(tot);
	for (auto [x, y, t] : G) {
		int cur = id[{x, y}];
		if (t == 1) e[cur].push_back(k + x);
		else if (t == 2) e[cur].push_back(k + n + y);
		else for (int d = 0; d < 8; d++) {
			int nx = x + dx[d], ny = y + dy[d];
			if (id.count({nx, ny}))
				e[cur].push_back(id[{nx, ny}]);
		}
	}
	for (int u = 1; u <= n + m + k; u++) if (!dfn[u]) tarjan(u);
	for (int u = 1; u <= n + m + k; u++)
		for (int v : e[u]) if (scc[u] != scc[v])
			g[scc[u]].push_back(scc[v]), ++deg[scc[v]];
	for (int u = 1; u <= cnt; u++) if (deg[u] == 0) q[tail++] = u, f[u] = val[u];
	while (head < tail) {
		int u = q[head++];
		for (int v : g[u]) {
			f[v] = max(f[v], f[u] + val[v]);
			if (--deg[v] == 0) q[tail++] = v;
		}
	}
	cout << *max_element(f + 1, f + cnt + 1) << '\n';
	return 0;
}
2024/6/26 09:40
加载中...