제출 #1324477

#제출 시각아이디문제언어결과실행 시간메모리
1324477kasamchi슈퍼트리 잇기 (IOI20_supertrees)C++20
21 / 100
1095 ms22116 KiB
#include "supertrees.h"
#include <bits/stdc++.h>
using namespace std;

int construct(vector<vector<int>> p) {
	int n = p.size();

	vector<int> grp(n);
	for (int i = 0; i < n; i++) {
		grp[i] = i;
	}

	auto fnd = [&] (auto &&self, int a) {
		if (grp[a] == a) {
			return a;
		} else {
			return grp[a] = self(self, grp[a]);
		}
	};

	vector<vector<int>> edge(n, vector(n, 0));
	for (int i = 0; i < n; i++) {
		for (int j = i + 1; j < n; j++) {
			if (p[i][j] == 2) {
				int x = fnd(fnd, i), y = fnd(fnd, j);
				grp[x] = y;
			}
		}
	}

	vector<bool> vis(n);
	for (int i = 0; i < n; i++) {
		if (!vis[i]) {
			vector<int> con = {i};
			vis[i] = true;
			for (int j = i + 1; j < n; j++) {
				int x = fnd(fnd, i), y = fnd(fnd, j);
				if (x == y) {
					con.push_back(j);
					vis[j] = true;
				}
			}
			if (con.size() == 1) {
				vis[i] = false;
				continue;
			}
			
			set<int> cyc;
			for (int u : con) {
				bool ok = true;
				for (int v : con) {
					if (u != v && p[u][v] != 2) {
						ok = false;
					}
				}
				if (ok) {
					cyc.insert(u);
				}
			}

			set<int> chn;
			for (int u : con) {
				if (!cyc.count(u)) {
					for (int v : con) {
						if (cyc.count(v) && p[u][v] != 2) {
							return 0;
						}
						if (!cyc.count(v) && p[u][v] != 1) {
							return 0;
						}
					}
					chn.insert(u);
				}
			}

			if (cyc.size() == 1 || cyc.size() + !chn.empty() == 2) {
				return 0;
			}
			for (auto it = next(cyc.begin()); it != cyc.end(); it++) {
				int u = *prev(it), v = *it;
				edge[u][v] = edge[v][u] = 1;
			}
			int t = *chn.begin(), u = *cyc.begin(), v = *cyc.rbegin();
			edge[u][t] = edge[t][u] = 1;
			edge[v][t] = edge[t][v] = 1;
			for (auto it = next(chn.begin()); it != chn.end(); it++) {
				int u = *prev(it), v = *it;
				edge[u][v] = edge[v][u] = 1;
			}
		}
	}

	for (int i = 0; i < n; i++) {
		if (!vis[i]) {
			for (int j = i + 1; j < n; j++) {
				if (p[i][j] == 1) {
					int x = fnd(fnd, i), y = fnd(fnd, j);
					if (x != y) {
						edge[i][j] = edge[j][i] = 1;
						grp[x] = y;
					}
				}
			}
		}
	}

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			if (p[i][j] == 0 && fnd(fnd, i) == fnd(fnd, j)) {
				return 0;
			}
		}
	}

	build(edge);
	return 1;
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...