This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
#define debug(...) //ignore
typedef long long ll;
typedef pair<int, int> pii;
typedef long double ld;
typedef vector<int> vi;
std::vector<int> find_reachable(std::vector<int> r, std::vector<int> u, std::vector<int> v, std::vector<int> c) {
int n = sz(r);
debug(debugging::PRINT_STRUCT_NAME = false);
struct info {
unordered_map<int,vi> locked_edges; // edges per color
vi unlocked_edges;
unordered_set<int> colors;
vi nodes;
int leader = -1;
};
vi where(n);
vector<info> comp(n);
rep(i,0,n) comp[i].leader = where[i] = i;
auto append = [&](vi&v, vi&q) {
if(sz(v) < sz(q)) swap(v,q);
for(int x : q) v.emplace_back(x);
q.clear();
};
auto unlock = [&](info &a, int col) {
if(a.colors.count(col)) return;
a.colors.emplace(col);
append(a.unlocked_edges, a.locked_edges[col]);
a.locked_edges.erase(col);
};
auto join = [&](int i, int j) {
if(sz(comp[i].nodes) < sz(comp[j].nodes)) swap(i, j);
info &a = comp[i];
info &b = comp[j];
//assert(!a.bad && !b.bad);
//assert(a.leader == i);
for(int x : b.nodes) where[x] = a.leader;
append(a.nodes, b.nodes);
append(a.unlocked_edges, b.unlocked_edges);
for(auto [col, v] : b.locked_edges) {
if(a.colors.count(col)) append(a.unlocked_edges, v);
else append(a.locked_edges[col], v);
}
for(int col : b.colors) unlock(a, col);
b.locked_edges.clear();
b.unlocked_edges.clear();
b.nodes.clear();
b.colors.clear();
};
auto find_edge = [&](info &a) {
while(sz(a.unlocked_edges) && where[a.unlocked_edges.back()] == a.leader)
a.unlocked_edges.pop_back();
if(sz(a.unlocked_edges)) return a.unlocked_edges.back();
return -1;
};
rep(x,0,n) comp[where[x]].nodes.emplace_back(x);
rep(i,0,sz(u)) {
int x = u[i], y = v[i], col = c[i];
comp[where[x]].locked_edges[col].emplace_back(y);
comp[where[y]].locked_edges[col].emplace_back(x);
}
rep(x,0,n) unlock(comp[where[x]], r[x]);
auto deb = [&](){
debug('%')
rep(i,0,n) if(comp[i].leader == i) {
//nassert(comp[i].leader == i);
debug();
debug(i);
debug(comp[i].nodes);
debug(comp[i].colors);
}
};
//deb();
vi done(n);
vi in_st(n);
vi st;
int min_size = 1e9;
function<void(int)> dfs = [&](int x) {
x = where[x];
if(done[x]) return;
if(sz(comp[x].nodes) > min_size) return;
if(in_st[x]) {
while(st.back() != x) {
int y = st.back();
st.pop_back();
in_st[y] = false;
//assert(y == where[y]);
join(where[x], y);
}
st.pop_back();
x = where[x];
in_st[x] = false;
}
st.emplace_back(x);
in_st[x] = true;
int y = find_edge(comp[x]);
if(y == -1) {
done[x] = true;
min_size = min(min_size, sz(comp[x].nodes));
}
else dfs(y);
done[x] = true;
};
rep(i,0,n) {
dfs(i);
for(int i : st) in_st[i] = false;
st.clear();
}
vi p(n,1e9);
rep(i,0,n) if(find_edge(comp[where[i]]) == -1)
p[i] = sz(comp[where[i]].nodes);
int mn = *min_element(all(p));
vector<int> ans(n,0);
rep(i,0,n) if(p[i] == mn) ans[i] = 1;
return ans;
}
Compilation message (stderr)
keys.cpp: In function 'std::vector<int> find_reachable(std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>)':
keys.cpp:84:8: warning: variable 'deb' set but not used [-Wunused-but-set-variable]
84 | auto deb = [&](){
| ^~~
# | 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... |