HDU 4912 Greedy

HDU4912


After choosing a point as the root, Greedy fills all the points with larger LCA first. Then all the points of the subtree rooted at LCA are points that can no longer be selected

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ls rt<<1
#define rs rt<<1|1
#define fi first
#define se second
#define pb push_back
using namespace std;
typedef long long ll;
typedef vector<int> VI;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const  ll inf  = 0x3f3f3f3f;
const int mod  = 20200501;
const int maxn = 2e5 + 6;
const int N    = 5e3 + 4;
const double eps = 1e-6;
ll qpow(ll x,ll y){
    
    ll ans=1;x%=mod; while(y){
    
     if(y&1) ans=ans*x%mod; x=x*x%mod; y>>=1;}return ans;}
int n,m,lgN,vis[maxn],fa[maxn][25],dep[maxn],id[maxn];
VI G[maxn];
void dfs(int u){
    
    
    dep[u]=dep[fa[u][0]]+1;
    for(int i=1;i<=lgN;i++){
    
    
        fa[u][i]=fa[fa[u][i-1]][i-1];
    }
    for(int v:G[u]) if(v!=fa[u][0]){
    
    
        fa[v][0]=u;
        dfs(v);
    }
}
void dfs1(int u){
    
    
    vis[u]=1;
    for(int v:G[u]) if(!vis[v]&&v!=fa[u][0]){
    
    
        dfs1(v);
    }
}
int LCA(int x,int y){
    
    
    if(dep[x]<dep[y]) swap(x,y);
    for(int i=lgN;i>=0;i--){
    
    
        if(dep[fa[x][i]]>=dep[y]) x=fa[x][i];
    }
    if(x==y) return x;
    for(int i=lgN;i>=0;i--){
    
    
        if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
    }
    return fa[x][0];
}
int a[maxn],b[maxn],c[maxn];

int main(){
    
    
    while(~scanf("%d%d",&n,&m)){
    
    
        for(int i=1;i<=n;i++){
    
    
            G[i].clear();
            id[i]=i;
            vis[i]=0;
        }
        lgN=(int)log(n)/log(2)+1;
        for(int i=1;i<n;i++){
    
    
            int u,v;scanf("%d%d",&u,&v);
            G[u].pb(v);G[v].pb(u);
        }
        dfs(1);
        for(int i=1;i<=m;i++){
    
    
            scanf("%d%d",&a[i],&b[i]);
            c[i]=LCA(a[i],b[i]);
        }
        sort(id+1,id+1+m,[](int x,int y){
    
    
                return dep[c[x]]>dep[c[y]];
        });
        int ans=0;
        for(int i=1;i<=m;i++){
    
    
            if(vis[a[id[i]]]||vis[b[id[i]]]) continue;
            dfs1(c[id[i]]);
            ans++;
            //cout<<id[i]<<',';
        }
        printf("%d\n",ans);
    }

}



Guess you like

Origin blog.csdn.net/qq_43914084/article/details/105930485