zoukankan      html  css  js  c++  java
  • hdu 6203 ping ping ping(LCA+树状数组)

    hdu 6203 ping ping ping(LCA+树状数组)

    题意:给一棵树,有m条路径,问至少删除多少个点使得这些路径都不连通

    (1 <= n <= 1e4)
    (1 <= m <= 5e4)

    思路:

    根据路径的LCA深度从大到小排序,每次选择一个没被删除的LCA删除
    当某个点删除时,跨越了以这个点为根的子树的路径都会被割断,而排序保证在同一子树内部的路径已经被处理过了,子树信息可以用dfs序来表示,区间操作可以用左右端点打标记,用树状数组维护即可。

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    const int N = 1e4 + 10;
    vector<int> G[N];
    int tot,in[N],out[N];
    int dep[N],f[N][20];
    int n;
    void dfs(int u,int fa,int d){
        in[u] = ++tot;
        f[u][0] = fa,dep[u] = d;
        for(int i = 1;i < 20;i++) f[u][i] = f[f[u][i-1]][i-1];
        for(auto v:G[u]) if(v != fa) dfs(v,u,d + 1);
        out[u] = tot;
    }
    int lca(int u,int v){
        if(dep[u] < dep[v]) swap(u,v);
        int d = dep[u] - dep[v];
        for(int i = 19;i >= 0 && u != v;i--) if(d & (1<<i)) u = f[u][i];
        if(u == v) return u;
        for(int i = 19;i >= 0;i--) if(f[u][i] != f[v][i]) u = f[u][i],v = f[v][i];
        return f[u][0];
    }
    int tr[N];
    int lowbit(int x){return x &(-x);}
    void up(int pos,int c){
        for(;pos <= n;pos += lowbit(pos)) tr[pos] += c;
    }
    int getsum(int pos){
        int ans = 0;
        for(;pos;pos -= lowbit(pos)) ans += tr[pos];
        return ans;
    }
    struct Q{
        int x,y,xy;
        Q(){};
        bool operator<(const Q&rhs)const{
            return dep[xy] > dep[rhs.xy];
        }
    }qr[100010];
    int main()
    {
        int u,v;
        while(scanf("%d",&n)==1){
            n++;
            for(int i = 1;i <= n;i++) {
                    G[i].clear();
                    tr[i] = 0;
            }
            for(int i = 1;i < n;i++){
                scanf("%d%d",&u,&v);u++,v++;
                G[u].push_back(v);
                G[v].push_back(u);
            }
            tot = 0;
            dfs(1,0,0);
            int q;
            scanf("%d",&q);
            for(int i = 0;i < q;i++){
                scanf("%d%d",&u,&v);u++,v++;
                qr[i].x = u,qr[i].y = v,qr[i].xy = lca(u,v);
            }
            sort(qr, qr + q);
            int ans = 0;
            for(int i = 0;i < q;i++){
                if(getsum(in[qr[i].x]) || getsum(in[qr[i].y])) continue;
                ans++;up(in[qr[i].xy],1),up(out[qr[i].xy]+1,-1);
            }
            cout<<ans<<endl;
        }
    
    
  • 相关阅读:
    实例化讲解RunLoop---IOS
    IOS中的SpringBoard
    Mac版OBS设置详解
    Swift学习Tip之Closures
    Swift中Array的Map
    IOS中的国际化(一)
    IOS,中获取系统内存占有率的方法
    IOS获取两个日期之间的时间间隔
    IOS中微信支、支付宝支付详解
    IOS中的正则表达式:NSRegularExpression
  • 原文地址:https://www.cnblogs.com/jiachinzhao/p/7525761.html
Copyright © 2011-2022 走看看