Submission #1312478

#TimeUsernameProblemLanguageResultExecution timeMemory
1312478hynmjRailway (BOI17_railway)C++20
100 / 100
117 ms46444 KiB
#include <bits/stdc++.h>
#define int long long
using namespace std;
const long long N = 2e5 + 5;
// const int N = 2e5 + 3;
int a[N];
vector<pair<int, int>> graph[N];
int SP[N][32];
int dist[N];
int mask;
int st[N];
int en[N];
int cnt[N];
vector<int> edges;
int ans = 0;
int now = 1;
int k;

void dfs(int node, int parent)
{
    SP[node][0] = parent;
    st[node] = now++;
    dist[node] = dist[parent] + 1;
    for (auto i : graph[node])
    {
        if (parent != i.first)
            dfs(i.first, node);
    }
    en[node] = now++;
}

int dfs2(int node, int parent)
{
    // cnt[node] = 0;
    for (auto i : graph[node])
    {
        if (parent != i.first)
        {
            cnt[node] += dfs2(i.first, node);
            if (cnt[i.first] >= k)
            {
                edges.push_back(i.second);
            }
        }
    }
    ans += cnt[node] >= k && node != 1;
    // en[node] = now++;
    return cnt[node];
}

void preprocess(int n)
{
    for (int p = 1; p < 22; p++)
    {
        for (int i = 1; i <= n; i++)
        {
            SP[i][p] = SP[SP[i][p - 1]][p - 1];
        }
    }
}

void go_up(int &k, int binary)
{
    for (int i = 0; i < 20; i++)
    {
        mask = 1LL << i;
        if ((binary & mask) != 0)
        {
            k = SP[k][i];
        }
    }
}

int same_at_height(int u, int v)
{
    if (u == v)
        return v;
    for (int i = 19; i >= 0; i--)
    {
        if (SP[u][i] != SP[v][i])
        {
            u = SP[u][i];
            v = SP[v][i];
        }
    }
    return SP[u][0];
}

int lca(int u, int v)
{
    if (dist[u] > dist[v])
        swap(u, v);
    int diff = dist[v] - dist[u];
    go_up(v, diff);
    if (u == v)
        return u;
    return same_at_height(u, v);
}
void solve()
{
    int n, m;
    cin >> n >> m >> k;
    // dist[0] = 1;

    int u, v;
    for (int i = 0; i < n - 1; i++)
    {
        cin >> u >> v;
        graph[u].emplace_back(v, i + 1);
        graph[v].emplace_back(u, i + 1);
    }
    dfs(1, 0);
    preprocess(n + 1);
    int nn;
    for (int i = 0; i < m; i++)
    {
        cin >> nn;
        vector<pair<int, int>> ls;
        for (int i = 0; i < nn; i++)
        {
            cin >> u;
            ls.push_back({st[u], u});
        }
        sort(ls.begin(), ls.end());

        for (int i = 0; i < nn - 1; i++)
        {
            int x = ls[i].second;
            int y = ls[i + 1].second;
            int lc = lca(x, y);
            ls.push_back({st[lc], lc});
        }
        sort(ls.begin(), ls.end());
        ls.erase(unique(ls.begin(), ls.end()), ls.end());
        vector<int> stac;
        for (auto &p : ls)
        {
            int x = p.second;
            while (!stac.empty() and en[stac.back()] < st[x])
                stac.pop_back();
            if (!stac.empty())
            {
                cnt[stac.back()]--;
                cnt[x]++;
            }
            stac.push_back(x);
        }
    }
    dfs2(1, 0);
    cout << edges.size() << endl;
    sort(edges.begin(), edges.end());
    for (auto i : edges)
    {
        cout << i << ' ';
    }
}

signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    cout.tie(NULL);
    int t = 1;
    // cin >> t;
    for (int i = 1; i <= t; i++)
    {
        // cout << "Case #" << i << ':' << ' ';
        solve();
        cout << endl;
    }
    return 0;
}
#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...