Submission #613963

#TimeUsernameProblemLanguageResultExecution timeMemory
613963thezomb1eSimurgh (IOI17_simurgh)C++17
30 / 100
3047 ms4472 KiB
#include "simurgh.h"
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define eb emplace_back
#define pb push_back
#define ft first
#define sd second
#define pi pair<int, int>
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define dbg(...) dbg_out(__VA_ARGS__)

using ll = long long;
using ld = long double;
using namespace std;
using namespace __gnu_pbds;

//Constants
const ll INF = 5 * 1e18;
const int IINF = 2 * 1e9;
const ll MOD = 1e9 + 7;
// const ll MOD = 998244353;
const ll dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
const ld PI = 3.14159265359;

//Templates
template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) {return os << '(' << p.first << ", " << p.second << ')';}
template<typename T_container, typename T = typename enable_if<!is_same<T_container, string>::value, typename T_container::value_type>::type> ostream& operator<<(ostream &os, const T_container &v) {os << '['; string sep; for (const T &x : v) os << sep << x, sep = ", "; return os << ']';}
void dbg_out() {cerr << endl;}
template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cerr << H << ' '; dbg_out(T...); }
template<typename T> void mins(T& x, T y) {x = min(x, y);}
template<typename T> void maxs(T& x, T y) {x = max(x, y);}
template<typename T> using oset = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template<typename T> using omset = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;


vector<int> find_roads(int n, vector<int> u, vector<int> v) {
	int m = u.size();
	vector<vector<pi>> e(n);
	for (int i = 0; i < m; i++) {
		e[u[i]].pb({v[i], i});
		e[v[i]].pb({u[i], i});	
	}
	vector<bool> take(m + 5, false); vector<bool> vis(n, false);
	function<void(int, int)> dfs_build = [&](int f, int p) {
		vis[f] = true;
		for (const auto &[to, id] : e[f]) {
			if (!vis[to]) {
				take[id] = true;
				dfs_build(to, f);
			}
		}
	};
	dfs_build(0, -1);
	vector<int> cycle, col(n, 0), par(n, -1);
	function<bool(int, int)> dfs_cycle = [&](int f, int p) {
		col[f] = 1;
		for (const auto &[to, id] : e[f]) {
			if (!take[id] || to == p) continue;
			if (col[to] == 1) {
				int cur = f;
				cycle.pb(id);
				while (cur != to) {
					cycle.pb(par[cur]);
					if (u[par[cur]] == cur) {
						cur = v[par[cur]];
					} else {
						cur = u[par[cur]];
					}
				}
				return true;
			} else if (col[to] == 0) {
				par[to] = id;
				if (dfs_cycle(to, f)) return true;
			}
		}
		col[f] = 2;
		return false;
	};
	int init;
	{
		vector<int> ar;
		for (int i = 0; i < m; i++) {
			if (take[i]) ar.pb(i);
		}
		init = count_common_roads(ar);
	}
	vector<int> ans(m + 5, -1);
	for (int i = 0; i < m; i++) {
		if (take[i]) continue;
		cycle.clear();
		par.assign(n, -1);
		col.assign(n, 0);
		take[i] = true;
		dfs_cycle(0, -1);
		int found = -1;
		for (int edge : cycle) {
			if (ans[edge] != -1) {
				found = edge;
				break;
			}
		}
		if (found == -1) {
			for (int edge : cycle) {
				if (edge == i) continue;
				take[edge] = false;
				vector<int> ar;
				for (int j = 0; j < m; j++) {
					if (take[j]) ar.pb(j);
				}
				take[edge] = true;
				int val = count_common_roads(ar);
				if (val - init == 1) {
					ans[i] = 1; ans[edge] = 0;
					found = i;
					break;
				} else if (val - init == -1) {
					ans[i] = 0; ans[edge] = 1;
					found = i;
					break;
				}
			}
			if (ans[i] == -1) {
				ans[i] = 0;
				found = i;
			}
		}
		for (int edge : cycle) {
			if (ans[edge] != -1) continue;
			int bef, aft;
			{
				vector<int> ar;
				take[found] = false;
				for (int j = 0; j < m; j++) {
					if (take[j]) ar.pb(j);
				}
				take[found] = true;
				aft = count_common_roads(ar);
			}
			{
				vector<int> ar;
				take[edge] = false;
				for (int j = 0; j < m; j++) {
					if (take[j]) ar.pb(j);
				}
				take[edge] = true;
				bef = count_common_roads(ar);
			}
			if (ans[found] == 0) {
				if (aft - bef == 1) {
					ans[edge] = 1;
				} else {
					ans[edge] = 0;
				}
			} else {
				if (aft - bef == 0) {
					ans[edge] = 1;
				} else {
					ans[edge] = 0;
				}
			}
		}
		take[i] = false;
	}
	vector<int> ret;
	for (int i = 0; i < m; i++) {
		if ((take[i] && ans[i] == -1) || ans[i] == 1) {
			ret.pb(i);
		}
	}
	return ret;
}
#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...