Untitled
unknown
plain_text
a year ago
5.3 kB
11
Indexable
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
#define fi first
#define se second
#define pp push_back
#define all(x) (x).begin(), (x).end()
#define Ones(n) __builtin_popcount(n)
#define endl '\n'
#define mem(arrr, xx) memset(arrr,xx,sizeof arrr)
//#define int long long
#define debug(x) cout << (#x) << " = " << x << endl
void Gamal() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
#ifdef Clion
freopen("input.txt", "r", stdin), freopen("output.txt", "w", stdout);
#endif
}
int dx[] = {+0, +0, -1, +1, +1, +1, -1, -1};
int dy[] = {-1, +1, +0, +0, +1, -1, +1, -1};
const double EPS = 1e-9;
const ll OO = 0X3F3F3F3F3F3F3F3F;
const int N = 2e5 + 5, INF = INT_MAX, MOD = 1e9 + 7, LOG = 20;
typedef vector<vector<int>> vvi;
typedef vector<bool> vb;
typedef vector<pii> vpi;
struct SCC {
vvi adj, adjRev, comps;
vpi edges;
vi revOut, compOf;
vb vis;
int N;
void init(int n) {
N = n;
adj.resize(n);
adjRev.resize(n);
vis.resize(n);
compOf.resize(n);
}
void addEdge(int u, int v) {
edges.emplace_back(u, v);
adj[u].push_back(v);
adjRev[v].push_back(u);
}
void dfs1(int u) {
vis[u] = true;
for (auto v: adj[u])
if (!vis[v])
dfs1(v);
revOut.push_back(u);
}
void dfs2(int u) {
vis[u] = true;
comps.back().push_back(u);
compOf[u] = comps.size() - 1;
for (auto v: adjRev[u])
if (!vis[v])dfs2(v);
}
void gen() {
fill(all(vis), false);
for (int i = 0; i < N; ++i) {
if (!vis[i])
dfs1(i);
}
reverse(all(revOut));
fill(all(vis), false);
for (auto node: revOut) {
if (vis[node])continue;
comps.push_back(vi());
dfs2(node);
}
}
vvi generateCondensedGraph() {
vvi adjCon(comps.size());
for (auto edge: edges)
if (compOf[edge.first] != compOf[edge.second])
adjCon[compOf[edge.first]].push_back(compOf[edge.second]);
return adjCon;
}
};
struct TwoSat {
int N;
vpi edges;
void init(int _N) {
N = _N;
}
int addVar() { return N++; }
// x or y, edges will be refined in the end
void either(int x, int y) {
x = max(2 * x, -1 - 2 * x);
y = max(2 * y, -1 - 2 * y);
edges.emplace_back(x, y);
}
void implies(int x, int y) {
either(~x, y);
}
void must(int x) {
either(x, x);
}
void XOR(int x, int y) {
either(x, y);
either(~x, ~y);
}
// void atMostOne exists in kactl
vb solve(int _N = -1) {
if (_N != -1) N = _N;
SCC scc;
scc.init(2 * N);
for (auto e: edges) {
scc.addEdge(e.first ^ 1, e.second);
scc.addEdge(e.second ^ 1, e.first);
}
scc.gen();
for (int i = 0; i < 2 * N; ++i) {
if (scc.compOf[i] == scc.compOf[i ^ 1])return {};
}
vvi comps = scc.comps;
reverse(all(comps));
vi compOf(2 * N);
for (int i = 0; i < comps.size(); ++i) {
for (auto e: comps[i])
compOf[e] = i;
}
vi tmp(comps.size());
for (int i = 0; i < comps.size(); ++i) {
if (!tmp[i]) {
tmp[i] = 1;
for (auto e: comps[i])
tmp[compOf[e ^ 1]] = -1;
}
}
vb ans(N);
for (int i = 0; i < N; ++i)
ans[i] = tmp[compOf[2 * i]] == 1;
return ans;
}
};
vector<int> clr[N], adj[N];
int n;
void dfs(int u, int par, TwoSat &st) {
for (auto v: adj[u]) {
if (v == par)continue;
st.implies(v,u);
dfs(v, u, st);
}
}
bool slv(int u, TwoSat st) {
st.must(u);
dfs(u, u, st);
vector<bool> ans = st.solve(2 * n);
if (ans.empty())return false;
for (int i = 0; i < 2 * n; ++i) {
if (ans[i]) {
cout << i + 1 << ' ';
}
}
cout << endl;
return true;
}
void solve() {
cin >> n;
for (int i = 0; i < n; ++i) {
clr[i].clear();
}
for (int i = 0; i < 2 * n; ++i) {
adj[i].clear();
}
for (int i = 0; i < 2 * n; ++i) {
int c;
cin >> c;
c--;
clr[c].push_back(i);
}
for (int i = 0; i < 2 * n - 1; ++i) {
int u, v;
cin >> u >> v;
u--, v--;
adj[u].push_back(v);
adj[v].push_back(u);
}
TwoSat st;
st.init(2 * n);
for (int i = 0; i < n; ++i) {
int u = clr[i][0], v = clr[i][1];
st.XOR(u, v);
}
if (slv(clr[0][0], st))return;
if (slv(clr[0][1], st))return;
cout << -1 << endl;
}
signed main() {
Gamal();
int t = 1;
cin >> t;
while (t--) {
solve();
}
}Editor is loading...
Leave a Comment