HDU 4912 Codicioso

HDU4912


Después de elegir un punto como raíz, Greedy llena primero todos los puntos con un LCA más grande. Entonces todos los puntos del subárbol arraigados en LCA son puntos que ya no se pueden seleccionar

#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);
    }

}



Supongo que te gusta

Origin blog.csdn.net/qq_43914084/article/details/105930485
Recomendado
Clasificación