Untitled
unknown
plain_text
a year ago
5.3 kB
6
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