Submission #1351445

#TimeUsernameProblemLanguageResultExecution timeMemory
1351445vahagngSplit the Attractions (IOI19_split)C++20
0 / 100
2 ms344 KiB
#include "split.h"
#include <bits/stdc++.h>
using namespace std;

const int N = 2e5 + 10;

vector<int>adj[N], r_adj[N];
int col[N], c[3], val[3], lst = 0;
bool visited[N];
int deg[N], sz[N], root = -1, A, B, NN, W[N], comp[N], CC, tin[N], fup[N], timer;
vector<int>comps[N];

set<pair<int, int>> bridges;

void dfs0(int node, int parent) {
	tin[node] = fup[node] = ++timer;
	visited[node] = 1;
	for (auto i : adj[node]) {
		if (i == parent) continue;
		if (visited[i]) {
			fup[node] = min(fup[node], tin[i]);
		}
		else {
			dfs0(i, node);
			fup[node] = min(fup[node], fup[i]);
			if (fup[i] > tin[node]) {
				bridges.insert({ i, node });
				bridges.insert({ node, i });
			}
		}
	}
}

void dfs_comp(int node, int CCC) {
	comp[node] = CCC;
	comps[CCC].push_back(node);
	visited[node] = 1;
	for (auto i : adj[node]) {
		if (visited[i]) continue;
		if (bridges.find({ node, i }) != bridges.end()) {
			continue;
		}
		dfs_comp(i, CCC);
	}
}

void dfs(int node, int parent) {
	sz[node] = W[node];
	for (auto i : adj[node]) {
		if (i == parent) continue;
		dfs(i, node);
		sz[node] += sz[i];
	}
}

bool mi_gagatov = 0;
int gagat = -1;

bool can_split(int node, int parent) {
	if (W[node] >= A + B) {
		gagat = node;
		mi_gagatov = 1;
		return 1;
	}
	vector<int> v;
	for (auto i : adj[node]) {
		v.push_back(sz[i]);
	}
	if (v.size() > 1) {
		sort(v.rbegin(), v.rend());
		int K = 0;
		for (auto i : v) {
			if (i >= A) {
				K = i;
			}
		}
		if (K != 0 && sz[node] - K >= B) {
			root = node;
			return 1;
		}
	}
	for (auto i : adj[node]) {
		if (i == parent) continue;
		int P = sz[i];
		sz[i] = sz[node];
		sz[node] = sz[node] - P;
		if (can_split(i, node)) {
			return 1;
		}
		sz[node] += P;
		sz[i] = P;
	}
	return 0;
}

void dfs_col(int node, int parent, int compo) {
	if (c[compo] == val[compo]) return;
	for (auto i : comps[node]) {
		c[compo]++;
		col[node] = compo;
		if (c[compo] == val[compo]) break;
	}
	visited[node] = 1;
	for (auto i : adj[node]) {
		if (i == parent || visited[i]) continue;
		dfs_col(i, node, compo);
	}
}

void dfs_col_mi_gagatov(int node, int compo) {
	if (c[compo] == val[compo]) return;
	c[compo]++;
	col[node] = compo + 1;
	visited[node] = 1;
	for (auto i : r_adj[node]) {
		if (visited[i] || bridges.find({ i, node }) != bridges.end()) continue;
		dfs_col_mi_gagatov(i, compo);
	}
}

vector<int> find_split(int n, int a, int b, int c, vector<int> p, vector<int> q) {
	vector<int> res;
	NN = n;
	for (int i = 0; i < p.size(); i++) {
		adj[p[i]].push_back(q[i]);
		adj[q[i]].push_back(p[i]);
		r_adj[p[i]].push_back(q[i]);
		r_adj[q[i]].push_back(p[i]);
		deg[p[i]]++;
		deg[q[i]]++;
	}
	dfs0(0, 0);
	for (int i = 0; i < n; i++) {
		visited[i] = 0;
	}
	for (int i = 0; i < n; i++) {
		if (visited[i]) continue;
		CC++;
		dfs_comp(i, CC);
	}
	for (int i = 0; i < n; i++) {
		W[comp[i]]++;
	}
	vector<pair<int, int>> edges;
	for (int i = 0; i < n; i++) {
		for (auto j : adj[i]) {
			if (comp[i] != comp[j]) {
				edges.push_back({ comp[i], comp[j] });
			}
		}
	}
	for (int i = 0; i < n; i++) {
		sort(r_adj[i].begin(), r_adj[i].end(), [&](int u, int v) {
			return deg[u] < deg[v];
			});
		adj[i].clear();
	}
	for (auto [u, v] : edges) {
		adj[u].push_back(v);
	}
	for (int i = 1; i <= CC; i++) {
		cerr << W[i] << endl;
		cerr << "adj[" << i << "] = [ ";
		for (auto j : adj[i]) cerr << j << ' ';
		cerr << "]\n";
	}
	vector<pair<int, int>>o;
	o.push_back({ a, 0 });
	o.push_back({ b, 1 });
	o.push_back({ c, 2 });
	sort(o.begin(), o.end());
	A = o[0].first;
	B = o[1].first;
	val[0] = a;
	val[1] = b;
	val[2] = c;
	dfs(1, 0);
	if (!can_split(1, 0)) {
		for (int i = 0; i < n; i++) {
			res.push_back(0);
		}
		return res;
	}
	if (mi_gagatov) {
		for (int i = 0; i < n; i++) {
			visited[i] = 0;
		}
		int g = -1;
		for (int i = 0; i < n; i++) {
			if (comp[i] == gagat && (g == -1 || deg[i] < deg[g])) {
				g = i;
			}
		}
		dfs_col_mi_gagatov(g, o[0].second);
		for (int i = 0; i < n; i++) {
			if (comp[i] == gagat && !visited[i]) {
				g = i;
			}
		}
		dfs_col_mi_gagatov(g, o[1].second);
		cerr << "!\n";
		for (int i = 0; i < n; i++) {
			if (col[i]) {
				res.push_back(col[i]);
			}
			else {
				res.push_back(o[2].second + 1);
			}
		}
		return res;
	}
	for (int i = 0; i < n; i++) {
		visited[i] = 0;
	}
	dfs(root, -1);
	vector<pair<int, int>> v;
	for (auto i : adj[root]) {
		v.push_back({ sz[i], i });
	}
	sort(v.rbegin(), v.rend());
	int pr = -1;
	for (auto i : v) {
		if (i.first >= A) {
			pr = i.second;
		}
	}
	dfs_col(pr, root, o[0].second);
	dfs_col(root, -1, o[1].second);
	for (int i = 0; i < n; i++) {
		if (!col[i]) {
			col[i] = o[2].second + 1;
		}
	}
	for (int i = 0; i < n; i++) {
		res.push_back(col[i]);
	}
	return res;
}
#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...