• HDU


    pro:给定N+1个点的树,有M对关键点,现在让你破坏最少的点,使得M对关键点不连通。

    sol:贪心,我们把M对点按照LCA深度排序,每次破坏LCA。 如果一对点(u,v,lca),u-lca-v有点被破坏,则可以不用破坏新的点。 我们可以用dfs序+树状数组来处理。 如果破坏了一个点,则给它的子树都+1。  那么u-lca-v有点被破坏等价于,u或者v至少一个属于已经被破坏的点的子树,树状数组查询即可。

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=200010;
    int fa[maxn][15],Laxt[maxn],Next[maxn],To[maxn],dep[maxn];
    int sum[maxn],cnt,in[maxn],times,out[maxn],ans;
    struct fcy{ int u,v,lca; }s[maxn];
    bool cmp(fcy x,fcy y){ return dep[x.lca]>dep[y.lca];}
    void add(int x,int val){ while(x<=times){ sum[x]+=val; x+=(-x)&x;}}
    int query(int x){int res=0; while(x){ res+=sum[x];x-=(-x)&x;}return res;}
    void adde(int u,int v){ Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v;}
    void dfs(int u,int f)
    {
        in[u]=++times;
        dep[u]=dep[f]+1; fa[u][0]=f;
        for(int i=Laxt[u];i;i=Next[i]){
            if(To[i]!=f) dfs(To[i],u);
        }
        out[u]=times;
    }
    int LCA(int u,int v)
    {
        if(dep[u]<dep[v]) swap(u,v);
        for(int i=14;i>=0;i--)
            if(dep[fa[u][i]]>=dep[v]) u=fa[u][i];
        if(u==v) return u;
        for(int i=14;i>=0;i--)
            if(fa[u][i]!=fa[v][i]) u=fa[u][i],v=fa[v][i];
        return fa[u][0];
    }
    int main()
    {
        int N,Q,u,v;
        while(~ scanf("%d",&N)){
            N++; ans=0;
            rep(i,1,N) Laxt[i]=0; cnt=0;
            rep(i,1,N-1){
               scanf("%d%d",&u,&v);
               u++; v++;
               adde(u,v); adde(v,u);
            }
            rep(i,1,times) sum[i]=0; times=0;
            dfs(1,0);
            rep(i,1,14) rep(j,1,N)
              fa[j][i]=fa[fa[j][i-1]][i-1];
            scanf("%d",&Q);
            rep(i,1,Q){
               scanf("%d%d",&s[i].u,&s[i].v);
               s[i].u++; s[i].v++;
               s[i].lca=LCA(s[i].u,s[i].v);
            }
            sort(s+1,s+Q+1,cmp);
            rep(i,1,Q){
               int t=query(in[s[i].u])+query(in[s[i].v]);
               if(!t) {
                  ans++;
                  add(in[s[i].lca],1);
                  add(out[s[i].lca]+1,-1);
               }
             }
             printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    【WPF】代码触发Button点击事件
    [WPF]静态资源(StaticResource)和动态资源(DynamicResource)
    stm32f103_arduino
    解除github下载的文件的锁定
    c# wpf binding
    mysql 使用可能遇到的问题
    c# progressbar
    STM32串口IAP(YModem) (转载)
    VS2017、VS2019安装包制作(转)
    八、ES集群搭建
  • 原文地址:https://www.cnblogs.com/hua-dong/p/10754831.html
Copyright © 2020-2023  润新知