제출 #863879

#제출 시각아이디문제언어결과실행 시간메모리
863879lolismekMergers (JOI19_mergers)C++14
100 / 100
1063 ms141136 KiB
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>

using namespace std;

const int NMAX = 5e5;
const int LGMAX = 19;

vector <int> adj[NMAX + 1];
int s[NMAX + 1];

int lvl[NMAX + 1];
int dp[NMAX + 1][LGMAX + 1];

void dfs1(int node, int parent){
    lvl[node] = lvl[parent] + 1;
    dp[node][0] = parent;

    for(int child : adj[node]){
        if(child != parent){
            dfs1(child, node);
        }
    }
}

int LCA(int a, int b){
    if(lvl[a] < lvl[b]){
        swap(a, b);
    }

    int diff = lvl[a] - lvl[b];
    for(int i = LGMAX; i >= 0; i--){
        if(diff & (1 << i)){
            a = dp[a][i];
        }
    }

    if(a == b){
        return a;
    }

    for(int i = LGMAX; i >= 0; i--){
        if(dp[a][i] != dp[b][i]){
            a = dp[a][i];
            b = dp[b][i];
        }
    }

    return dp[a][0];
}

int glca[NMAX + 1];
int bad[NMAX + 1];

int dfs2(int node, int parent){
    int mini = lvl[glca[s[node]]];

    for(int child : adj[node]){
        if(child != parent){
            mini = min(mini, dfs2(child, node));
        }
    }

    if(mini >= lvl[node]){
        bad[node] = parent;
    }

    return mini;
}

int Id = 0;
int id[NMAX + 1];

void dfs3(int node, int parent){
    if(bad[node] == parent){
        id[node] = ++Id;
    }else{
        id[node] = id[parent];
    }

    for(int child : adj[node]){
        if(child != parent){
            dfs3(child, node);
        }
    }
}

vector <int> T[NMAX + 1];

void dfs4(int node, int parent){
    for(int child : adj[node]){
        if(child != parent){
            if(id[child] != id[node]){
                T[id[node]].push_back(id[child]);
                T[id[child]].push_back(id[node]);
            }
            dfs4(child, node);
        }
    }
}

int main(){

    int n, k;
    cin >> n >> k;

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

    for(int i = 1; i <= n; i++){
        cin >> s[i];
    }

    dfs1(1, 0);

    for(int j = 1; (1 << j) <= n; j++){
        for(int i = 1; i <= n; i++){
            dp[i][j] = dp[dp[i][j - 1]][j - 1];
        }
    }

    for(int i = 1; i <= n; i++){
        if(glca[s[i]] == 0){
            glca[s[i]] = i;
        }else{
            glca[s[i]] = LCA(glca[s[i]], i);
        }
    }

    dfs2(1, 0);
    dfs3(1, 0);
    dfs4(1, 0);

    int leafs = 0;
    for(int i = 1; i <= Id; i++){
        sort(T[i].begin(), T[i].end());
        T[i].erase(unique(T[i].begin(), T[i].end()), T[i].end());

        if((int)T[i].size() == 1){
            leafs++;
        }
    }

    cout << (leafs / 2) + (leafs % 2) << '\n';

    return 0;
}

/*
5 4
1 2
2 3
3 4
3 5
1
2
1
3
4
*/
#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...