#include "simurgh.h"
#include "bits/stdc++.h"
using namespace std;
#define ff first
#define ss second
mt19937 rng(213124);
int rand(int l, int r) {
int x = rng();
return abs(x) % (r - l + 1) + l;
}
struct dsu {
vector<vector<int>> childs;
vector<int> par;
void init(int n) {
childs.assign(n, {});
par.assign(n, 0);
for (int i = 0; i < n; i++) par[i] = i, childs[i].emplace_back(i);
}
int get(int a) { return par[a]; }
void merge(int a, int b) {
if (par[a] == par[b]) return;
a = par[a]; b = par[b];
if (childs[a].size() < childs[b].size()) swap(a, b);
for (int x: childs[b]) {
par[x] = a;
childs[a].emplace_back(x);
}
childs[b].clear();
}
};
std::vector<int> find_roads(int n, std::vector<int> U, std::vector<int> V) {
vector<pair<int, int>> all;
for (int i = 0; i < U.size(); i++) all.emplace_back(min(U[i], V[i]), max(U[i], V[i]));
vector gold(n, vector(n, -1));
dsu edge; edge.init(U.size());
vector vis(U.size(), false);
while (true) {
dsu ds; ds.init(n);
vector<int> used;
for (int i = 0; i < all.size(); i++) {
if (gold[all[i].ff][all[i].ss] == 1) {
vis[i] = true;
used.emplace_back(i);
ds.merge(all[i].ff, all[i].ss);
}
}
for (int i = 0; i < all.size(); i++) {
if (ds.get(all[i].ff) == ds.get(all[i].ss)) continue;
ds.merge(all[i].ff, all[i].ss);
used.emplace_back(i);
}
int old = count_common_roads(used);
if (old == n - 1) {
return used;
}
// for (int x: used) cout << x << ' ';
// cout << endl;
// for (int i = 0; i < n - 1; i++) swap(used[i], used[rand(0, i)]);
// for (int i = 0; i < n; i++) for (int j = i + 1; j < n; j++) {
// if (gold[i][j] != -1) {
// cout << i << ' ' << j << ' ' << gold[i][j] << endl;
// }
// }
for (int i = 0; i < U.size(); i++) {
if (vis[i]) continue;
vis[i] = true;
ds.init(n);
ds.merge(all[i].ff, all[i].ss);
bool bad = false;
vector<int> shit = {i};
int wh;
for (int j: used) {
auto [u, v] = all[j];
if (ds.get(u) == ds.get(v) and gold[u][v] == 1) bad = true;
if (ds.get(u) != ds.get(v)) {
shit.emplace_back(j);
}
else wh = j;
ds.merge(u, v);
}
if (bad) {
gold[all[i].ff][all[i].ss] = gold[all[i].ss][all[i].ff] = 0;
continue;
}
int nw = count_common_roads(shit);
if (old == nw) {
edge.merge(i, wh);
} else if (old + 1 == nw) {
for (int x: edge.childs[edge.get(i)]) {
auto [u, v] = all[x];
gold[u][v] = gold[v][u] = 1;
}
for (int x: edge.childs[edge.get(wh)]) {
auto [u, v] = all[x];
gold[u][v] = gold[v][u] = 0;
}
} else if (old - 1 == nw) {
for (int x: edge.childs[edge.get(i)]) {
auto [u, v] = all[x];
gold[u][v] = gold[v][u] = 0;
}
for (int x: edge.childs[edge.get(wh)]) {
auto [u, v] = all[x];
gold[u][v] = gold[v][u] = 1;
}
}
break;
}
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |