Submission #105867

#TimeUsernameProblemLanguageResultExecution timeMemory
105867JustasZMergers (JOI19_mergers)C++14
100 / 100
1881 ms152384 KiB
#include <bits/stdc++.h>
#define pb push_back
#define x first
#define y second
#define all(a) a.begin(), a.end()
#define sz(a) (int)a.size()
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int>pii;
const int maxn = 5e5 + 100;
const int mod = 1e9 + 7;
mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
int n, k, anc[maxn][20], dep[maxn], par[maxn], highest[maxn];
vector<int>adj[maxn], grp[maxn], g[maxn];
void predfs(int v)
{
    dep[v] = dep[anc[v][0]] + 1;
    for(int i = 1; i < 20; i++)
        anc[v][i] = anc[anc[v][i - 1]][i - 1];
    for(int to : adj[v])
    {
        if(to != anc[v][0])
        {
            anc[to][0] = v;
            predfs(to);
        }
    }
}
int lca(int a, int b)
{
    if(dep[a] > dep[b]) swap(a, b);
    for(int i = 19; i >= 0; i--)
        if(dep[anc[b][i]] >= dep[a])
            b = anc[b][i];
    if(a == b) return a;
    for(int i = 19; i >= 0; i--)
        if(anc[a][i] != anc[b][i])
            a = anc[a][i], b = anc[b][i];
    return anc[a][0];
}
int root(int v)
{
    return v == par[v] ? v : par[v] = root(par[v]);
}
void unite(int a, int b)
{
    a = root(a), b = root(b);
    if(a == b) return;
    par[b] = a;
    if(dep[highest[b]] < dep[highest[a]])
        highest[a] = highest[b];
}
int main()
{
    ios_base::sync_with_stdio(false), cin.tie(0);
    cin >> n >> k;
    for(int i = 1; i <= n; i++)
        par[i] = i;
    for(int i = 0; i < n - 1; i++)
    {
        int a, b;
        cin >> a >> b;
        adj[a].pb(b);
        adj[b].pb(a);
    }
    predfs(1);
    for(int i = 1; i <= n; i++)
    {
        int g; cin >> g;
        grp[g].pb(i);
    }
    for(int kk = 1; kk <= k; kk++)
    {
        int LCA = -1;
        for(int a : grp[kk])
        {
            if(LCA == -1)
                LCA = a;
            else
                LCA = lca(LCA, a);
        }
        for(int a : grp[kk])
        {
            highest[root(a)] = LCA;
        }
    }
    vector<int>ord;
    for(int i = 1; i <= n; i++)
        ord.pb(i);
    sort(all(ord), [&](int a, int b)
         {
             return dep[a] > dep[b];
         });
    for(int v : ord)
    {
        if(highest[root(v)] == v)
            continue;
        else
            unite(v, anc[v][0]);
    }
    for(int i = 1; i <= n; i++)
    {
        for(int to : adj[i])
        {
            if(root(i) < root(to))
            {
                g[root(i)].pb(root(to));
                g[root(to)].pb(root(i));
            }
        }
    }
    int leaves = 0;
    for(int i = 1; i <= n; i++)
        if(sz(g[i]) == 1) ++leaves;
    cout << (leaves + 1) / 2 << "\n";
    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...