제출 #1228596

#제출 시각아이디문제언어결과실행 시간메모리
1228596colossal_pepeSplit the Attractions (IOI19_split)C++20
40 / 100
68 ms23112 KiB
#include "split.h"
#include <bits/stdc++.h>
using namespace std;

const pair<int, int> null_pair = make_pair(-1, -1);

int n, m;
vector<vector<int>> g, t;
vector<int> abc, idx = {0, 1, 2};
vector<int> subt_n;

void makeLongTree() {
	int root = 0;
	for (int i = 0; i < n; i++) {
		sort(g[i].begin(), g[i].end(), [](int v1, int v2) {
			return g[v1].size() > g[v2].size();
		});
		if (g[i].size() > g[root].size()) root = i;
	}
	t.resize(n);
	vector<bool> vis(n, 0);
	auto dfs = [&](const auto &self, int u) -> void {
		vis[u] = 1;
		for (int v : g[u]) {
			if (vis[v]) continue;
			t[u].push_back(v);
			t[v].push_back(u);
			self(self, v);
		}
	};
	dfs(dfs, root);
}

vector<int> split(pair<int, int> e) {
	if (e == null_pair) return vector<int>(n, 0);
	auto [x, y] = e;
	vector<int> ret(n, 2);
	int c = 0;
	auto dfs = [&](const auto &self, int u, int par) -> void {
		if (abc[c]) ret[u] = c, abc[c]--;
		for (int v : t[u]) {
			if (v == par) continue;
			self(self, v, u);
		}
	};
	dfs(dfs, x, y);
	c = 1;
	dfs(dfs, y, x);
	for (int &x : ret) x = idx[x] + 1;
	return ret;
}

vector<int> findSplit() {
	subt_n.resize(n);
	auto dfs1 = [&](const auto &self, int u, int par) -> void {
		subt_n[u] = 1;
		for (int v : t[u]) {
			if (v == par) continue;
			self(self, v, u);
			subt_n[u] += subt_n[v];
		}
	};
	dfs1(dfs1, 0, 0);
	auto dfs2 = [&](const auto &self, int u, int par) -> pair<int, int> {
		if (abc[0] <= subt_n[u] and abc[1] <= n - subt_n[u]) {
			return make_pair(u, par);
		}
		if (abc[1] <= subt_n[u] and abc[0] <= n - subt_n[u]) {
			return make_pair(par, u);
		}
		for (int v : t[u]) {
			if (v == par) continue;
			auto res = self(self, v, u);
			if (res != null_pair) return res;
		}
		return null_pair;
	};
	return split(dfs2(dfs2, 0, 0));
}

vector<int> find_split(int N, int A, int B, int C, vector<int> U, vector<int> V) {
	n = N, m = U.size();
	abc = vector<int>{A, B, C};
	sort(idx.begin(), idx.end(), [](int i, int j) {
		return abc[i] < abc[j];
	});
	sort(abc.begin(), abc.end());
	g.resize(n);
	for (int i = 0; i < m; i++) {
		g[U[i]].push_back(V[i]);
		g[V[i]].push_back(U[i]);
	}
	makeLongTree();
	return findSplit();
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...