# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
1073020 | 2024-08-24T08:42:28 Z | mc061 | 슈퍼트리 잇기 (IOI20_supertrees) | C++14 | 0 ms | 0 KB |
#include <bits/stdc++.h> using namespace std; const int N = 1001; struct DSU { vector<int> p; vector<vector<int>> els; DSU() { p.resize(N); els.resize(N); iota(p.begin(), p.end(), 0); for (int i = 0; i < N; ++i) { els[i].push_back(i); } } int get(int a) { return p[a] = (a == p[a] ? a : get(p[a])); } void merge(int a, int b) { int x = get(a); int y = get(b); if (x == y) return; if (els[x].size() > els[y].size()) { swap(x, y); } p[x] = y; while (els[x].size()) els[y].push_back(els[x].back()), els[x].pop_back(); } }; void build(vector<vector<int>> b); int construct(const vector<vector<int>>& p) { DSU lines; const int n = p.size(); vector<vector<int>> b(n, vector<int>(n, 0)); for (int i = 0; i < n; ++i) { for (int j = i+1; j < n; ++j) { if (p[i][j] == 1) { int x = lines.get(i); int y = lines.get(j); if (x != y) { b[i][j] = b[j][i] = 1; lines.merge(x, y); } } } } DSU comps; for (int i = 0; i < n; ++i) { for (int j = i+1; j < n; ++j) { if (p[i][j] > 0) comps.merge(i, j); } } vector<bool> vis(n, false); for (int i = 0; i < n; ++i) { int j = comps.get(i); if (vis[j]) continue; vis[j] = true; vector<int> vs = comps.els[j]; vector<int> twos; vector<bool> vis_lines(n, false); for (int k = 0; k < vs.size(); ++k) { int v = vs[k]; if (vis_lines[lines.get(v)]) continue; int u = lines.els[lines.get(v)].front(); twos.push_back(u); vis_lines[lines.get(v)] = true; } if (twos.size() == 1) continue; for (int k = 0; k < twos.size(); ++k) { int nxt = (k+1)%twos.size(); b[twos[k]][twos[nxt]] = b[twos[nxt]][twos[k]] = 1; } } build(b); return true; }