Submission #834984

#TimeUsernameProblemLanguageResultExecution timeMemory
834984pavementThousands Islands (IOI22_islands)C++17
9.10 / 100
25 ms4180 KiB
#include "islands.h"
#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define eb emplace_back

using ii = pair<int, int>;

vector<int> cyc, path;
vector<bool> vis;
vector<vector<ii> > adj;

namespace ufds {
	vector<int> lnk, sz, num_edges;
	
	void init(int n) {
		lnk.resize(n);
		iota(lnk.begin(), lnk.end(), 0);
		sz.resize(n);
		fill(sz.begin(), sz.end(), 1);
		num_edges.resize(n);
		fill(num_edges.begin(), num_edges.end(), 0);
	}
	int find(int x) {
		if (x == lnk[x]) {
			return x;
		}
		return lnk[x] = find(lnk[x]);
	}
	void unite(int a, int b) {
		a = find(a);
		b = find(b);
		if (a == b) {
			return;
		}
		if (sz[b] > sz[a]) {
			swap(a, b);
		}
		sz[a] += sz[b];
		num_edges[a] += num_edges[b];
		lnk[b] = a;
	}
};

int dfs(int u) {
	vis[u] = 1;
	for (auto [v, idx] : adj[u]) {
		if (vis[v]) {
			cyc.pb(idx);
			return v;
		}
	}
	for (auto [v, idx] : adj[u]) {
		int tmp = dfs(v);
		if (tmp != -1) {
			if (tmp == -2) {
				path.pb(idx);
			} else {
				cyc.pb(idx);
				if (tmp == u) {
					tmp = -2;
				}
			}
			return tmp;
		}
	}
	return -1;
}

variant<bool, vector<int> > find_journey(int N, int M, vector<int> U, vector<int> V) {
	ufds::init(N);
	adj.resize(N);
	for (int i = 0; i < M; i++) {
		if (i % 2 == 0) {
			adj[U[i]].eb(V[i], i);
			ufds::unite(U[i], V[i]);
			ufds::num_edges[ufds::find(U[i])]++;
		}
	}
	if (ufds::num_edges[ufds::find(0)] != ufds::sz[ufds::find(0)] - 1) {
		vis.resize(N);
		dfs(0);
		reverse(path.begin(), path.end());
		reverse(cyc.begin(), cyc.end());
		vector<int> out;
		for (int i : path) {
			out.pb(i);
		}
		for (int i : cyc) {
			out.pb(i);
		}
		reverse(cyc.begin(), cyc.end());
		for (int i : cyc) {
			out.pb(i ^ 1);
		}
		for (int i : cyc) {
			out.pb(i);
		}
		reverse(cyc.begin(), cyc.end());
		for (int i : cyc) {
			out.pb(i ^ 1);
		}
		reverse(cyc.begin(), cyc.end());
		reverse(path.begin(), path.end());
		for (int i : path) {
			out.pb(i);
		}
		return out;
	} else {
		vector<int> deg(N, 0);
		for (int i = 0; i < M; i++) {
			if (ufds::find(U[i]) == ufds::find(0)) {
				deg[U[i]]++;
			}
		}
		if (deg[0] > 1 || *max_element(deg.begin(), deg.end()) > 2) {
			if (deg[0] > 1) {
				vector<int> outgoing;
				for (int i = 0; i < M; i++) {
					if (U[i] == 0) {
						outgoing.pb(i);
					}
				}
				auto ret = {outgoing[0], outgoing[0] ^ 1, outgoing[1], outgoing[1] ^ 1, outgoing[0] ^ 1, outgoing[0], outgoing[1] ^ 1, outgoing[1]};
				return ret;
			} else {
				return true;
			}
		} else {
			return false;
		}
	}
}
#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...