Submission #827110

#TimeUsernameProblemLanguageResultExecution timeMemory
827110Sohsoh84Keys (IOI21_keys)C++17
100 / 100
2638 ms166024 KiB
#include "keys.h"
#include <bits/stdc++.h>

using namespace std;

#define sep		' '
#define debug(x)	cerr << #x << ": " << x << endl;

const int MAXN = 1e6 + 10;

int sz[MAXN], F[MAXN], par[MAXN], n, m, R[MAXN], T[MAXN], from[MAXN], to[MAXN];
bool dead[MAXN], vis[MAXN], tvis[MAXN];
vector<int> dfs_vec, C[MAXN], adj[MAXN];
bool dfs_finished;

inline int f(int ind, int v) {
	return from[ind] ^ to[ind] ^ v;
}

inline bool unite(int u, int v) { // check the order
	u = par[u], v = par[v];
	if (u == v) return false;

	int tf = F[v];
	
	if (C[u].size() < C[v].size()) swap(u, v);
	for (int e : C[v]) {
		par[e] = u;
		C[u].push_back(e);
	}

	F[u] = tf;
	C[v].clear();

	return true;
}

int fuck;
vector<int> key_vis, vert_vis, unlock[MAXN];
set<int> keys;

void add_key(int x);

void add_vert(int v) {
	if (dfs_finished) return;

	if (par[v] != fuck) {
		if (dead[v]) {
			for (int e : C[fuck])
				dead[e] = true, sz[e] = MAXN;
		} else {
			unite(fuck, v);
			tvis[par[v]] = true;
		}

		dfs_finished = true;
		return;
	}

	if (vis[v]) return;


	dfs_vec.push_back(v);

	vis[v] = true;
	vert_vis.push_back(v);
	add_key(R[v]);

	for (int ind : adj[v]) {
		key_vis.push_back(T[ind]);
		if (keys.find(T[ind]) != keys.end())
			add_vert(f(ind, v));
		else
			unlock[T[ind]].push_back(f(ind, v));
	
		if (dfs_finished) return;
	}
}

void add_key(int x) {
	if (dfs_finished) return;

	key_vis.push_back(x);
	keys.insert(x);
	for (int e : unlock[x]) {
		add_vert(e);

		if (dfs_finished) return;
	}
}

inline void bruvka() {
	memset(tvis, false, sizeof tvis);
	for (int vv = 0; vv < n; vv++) {
		if (!dead[vv] && !tvis[par[vv]]) {
			int v = F[par[vv]];
			fuck = par[vv];

			add_vert(v);	
			if (!dfs_finished) {
				for (int e : dfs_vec)
					sz[e] = dfs_vec.size();
			
				for (int e : C[fuck]) {
					dead[e] = true;
					if (!sz[e]) sz[e] = MAXN;
				}
			}

			dfs_finished = false;
			for (int e : dfs_vec) vis[e] = false;
			dfs_vec.clear();
	
			keys.clear();
			for (int e : key_vis) unlock[e].clear();
			for (int e : vert_vis) vis[e] = false;

			key_vis.clear();
			vert_vis.clear();
		}
	}
}

vector<int> find_reachable(vector<int> r_, vector<int> u_, vector<int> v_, vector<int> c_) {
	n = r_.size(), m = u_.size();
	for (int i = 0; i < m; i++) {
		adj[u_[i]].push_back(i);
		adj[v_[i]].push_back(i);
		from[i] = v_[i];
		to[i] = u_[i];
		T[i] = c_[i];
	}

	for (int i = 0; i < n; i++)
		R[i] = r_[i];

	vector<int> fans(r_.size(), 1);
	
	for (int i = 0; i < n; i++) {
		par[i] = i;
		C[i] = {i};
		F[i] = i;
	}

	for (int i = 0; i < 20; i++) // TODO
		bruvka();
/*	
	for (int i = 0; i < n; i++) {
		cerr << F[par[i]] << sep;
	}

	cerr << endl;

	for (int i = 0; i < n; i++)
		cerr << sz[i] << sep;
	cerr << endl;
*/
	int mn = *min_element(sz, sz + n);
	for (int i = 0; i < n; i++)
		fans[i] = (sz[i] == mn);

	return fans;
}
#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...