Untitled

 avatar
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