Submission #1104801

#TimeUsernameProblemLanguageResultExecution timeMemory
1104801_callmelucianJail (JOI22_jail)C++14
100 / 100
1615 ms327208 KiB
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pl;
typedef pair<int,int> pii;
typedef tuple<int,int,int> tt;

#define all(a) a.begin(), a.end()
#define filter(a) a.erase(unique(all(a)), a.end())

const int NODE = 5e6 + 6, mn = 1e5 + 2e4 + 4, LOG = 17;
int up[mn][LOG], vis[NODE], depth[mn], n, m;
vector<int> adj[mn], graph[NODE];

// layer 0: nodes
// layer 1: prisoner
// layer 2: starting points
// layer 3: ending points

int node (int layer, int l2, int u) {
    if (layer == 0) return u;
    if (layer == 1) return m + l2 * n + u;
    if (layer == 2) return m + (l2 + LOG) * n + u;
}

void addEdge (int a, int b) {
    graph[a].push_back(b);
}

void dfs (int u, int p, int d) {
    up[u][0] = p, depth[u] = d;
    for (int i = 1; i < LOG; i++) {
        addEdge(node(1, i - 1, u), node(1, i, u)), addEdge(node(1, i - 1, up[u][i - 1]), node(1, i, u));
        addEdge(node(2, i, u), node(2, i - 1, u)), addEdge(node(2, i, u), node(2, i - 1, up[u][i - 1]));
        up[u][i] = up[up[u][i - 1]][i - 1];
    }

    for (int v : adj[u])
        if (v != p) dfs(v, u, d + 1);
}

int goUp (int a, int k) {
    for (int i = 0; i < LOG; i++)
        if (k & (1 << i)) a = up[a][i];
    return a;
}

int lca (int a, int b) {
    if (depth[a] < depth[b]) swap(a, b);
    a = goUp(a, depth[a] - depth[b]);
    if (a == b) return a;
    for (int i = LOG - 1; i >= 0; i--)
        if (up[a][i] != up[b][i]) a = up[a][i], b = up[b][i];
    return up[a][0];
}

void connect (int pivot, int u, int k, bool from) {
    for (int i = 0; i < LOG; i++) {
        if ((k & (1 << i)) == 0) continue;
        if (from) addEdge(pivot, node(2, i, u));
        else addEdge(node(1, i, u), pivot);
        u = up[u][i];
    }
}

void refresh (int n, int sumNode) {
    for (int i = 0; i <= n; i++) adj[i].clear();
    for (int i = 0; i <= sumNode; i++)
        graph[i].clear(), vis[i] = 0;
}

vector<int> line;

bool detectCycle (int u) {
    if (vis[u] == 1) return 1;
    if (vis[u] == 2) return 0;
    vis[u] = 1;
    line.push_back(u);
    for (int v : graph[u])
        if (detectCycle(v)) return vis[u] = 2, 1;
    return vis[u] = 2, 0;
}

bool solve() {
    cin >> n;
    for (int i = 1; i < n; i++) {
        int a, b; cin >> a >> b;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }

    cin >> m;
    vector<pii> paths(m + 1);

    for (int i = 1; i <= m; i++)
        cin >> paths[i].first >> paths[i].second;

    // build graph
    dfs(1, 1, 0);
    for (int i = 1; i <= m; i++) {
        int a, b; tie(a, b) = paths[i];
        int lc = lca(a, b);

        // from start point to this path
        connect(node(0, 0, i), up[a][0], depth[a] - depth[lc], 0);
        connect(node(0, 0, i), b, depth[b] - depth[lc], 0);

        // from this path to end point
        connect(node(0, 0, i), up[b][0], depth[b] - depth[lc], 1);
        connect(node(0, 0, i), a, depth[a] - depth[lc], 1);

        addEdge(node(0, 0, i), node(1, 0, a));
        addEdge(node(2, 0, b), node(0, 0, i));
    }

    // detect cycle
    int sumNode = m + 2 * LOG * n;
    for (int i = 1; i <= sumNode; i++)
        if (!vis[i] && detectCycle(i)) return refresh(n, sumNode), 0;

    return refresh(n, sumNode), 1;
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    int TC; cin >> TC;
    while (TC--) cout << (solve() ? "Yes" : "No") << "\n";

    return 0;
}

Compilation message (stderr)

jail.cpp: In function 'int node(int, int, int)':
jail.cpp:26:1: warning: control reaches end of non-void function [-Wreturn-type]
   26 | }
      | ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...