Submission #1353903

#TimeUsernameProblemLanguageResultExecution timeMemory
1353903kokokaiMergers (JOI19_mergers)C++20
100 / 100
668 ms157616 KiB
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define fi first
#define se second
#define task "text"

const int N = 5e5+5;
const int LG = 20;
vector<int> adj[N];
int pre[N],dp[N],con[N],name[N];
int n,k;
int S[N];
vector<int> gr[N];
int anc[N][LG],h[N];
map<pair<int,int>,int> mp;
void dfs(int u,int p){
    h[u]=h[p]+1;
    anc[u][0]=p;
    for(int lg=1;lg<LG;lg++) anc[u][lg]=anc[anc[u][lg-1]][lg-1];
    for(int v:adj[u]){
        if(v==p) continue;
        dfs(v,u);
    }
}
void dfs1(int u,int p){
    for(int v:adj[u]){
        if(v==p) continue;
        dfs1(v,u);
        pre[u] += pre[v];
    }
    if(pre[u] == 0 && u>1){
        mp[{min(u,p),max(u,p)}]=1;
    }
}
void dfs2(int u,int p){
    dp[u]=(pre[u]==0);
    for(int v:adj[u]){
        if(v==p) continue;
        dfs2(v,u);
        con[u] += (dp[v]>0);
        if(dp[v]>0) name[u]=v;
        dp[u] += dp[v];
    }
}
int findroot(int u,int p){
    if(con[u] == 1){
        return findroot(name[u],u);
    }
    return u;
}
int lca(int u,int v){
    if(h[u]<h[v]) swap(u,v);
    int d=h[u]-h[v];
    for(int lg=LG-1;lg>=0;lg--){
        if((d&(1<<lg))>0) u=anc[u][lg];
    }
    if(u==v) return u;
    for(int lg=LG-1;lg>=0;lg--){
        if(anc[u][lg] != anc[v][lg]){
            u=anc[u][lg];
            v=anc[v][lg];
        }
    }
    return anc[u][0];
}
pair<int,int> e[N];
int vis[N];
int comp[N],deg[N];
int curid=1;
void dfs3(int u){
    vis[u]=1;
    comp[u]=curid;
    for(int v:adj[u]){
        if(vis[v]) continue;
        if(mp.find({min(u,v),max(u,v)}) == mp.end()){
            dfs3(v);
        }
    }
}
int main(){
    ios::sync_with_stdio(false);cin.tie(nullptr);
    if(fopen(task".inp","r")){
        freopen(task".inp","r",stdin);
    }
    cin>>n>>k;
    for(int i=1;i<n;i++){
        int u,v;
        cin>>u>>v;
        e[i]={u,v};
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    for(int i=1;i<=n;i++){
        cin>>S[i];
        gr[S[i]].push_back(i);
    }
    dfs(1,0);

    for(int g=1;g<=k;g++){
        if(gr[g].empty()) continue;
        int lc=gr[g][0];
        for(int v:gr[g]) lc=lca(v,lc);
        for(int v:gr[g]){
            pre[v]++;
            pre[lc]--;
        }
    }
    dfs1(1,0);
    for(int i=1;i<=n;i++){
        if(!vis[i]){
            dfs3(i);
            ++curid;
        }
    }
    for(int i=1;i<n;i++){
        int u=e[i].fi,v=e[i].se;
        if(comp[u] != comp[v]){
            deg[comp[u]]++;
            deg[comp[v]]++;
        }
    }
    int leaf=0;
    for(int i=1;i<=n;i++){
        if(deg[i]==1) leaf++;
    }
    cout<<(leaf+1)/2<<'\n';
}

Compilation message (stderr)

mergers.cpp: In function 'int main()':
mergers.cpp:84:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   84 |         freopen(task".inp","r",stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...