hdu 6203 ping ping ping(LCA+樹狀數組)

hdu 6203 ping ping ping(LCA+樹狀數組)

題意:給一棵樹,有m條路徑,問至少刪除多少個點使得這些路徑都不連通

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

思路:

根據路徑的LCA深度從大到小排序,每次選擇一個沒被刪除的LCA刪除
當某個點刪除時,跨越了以這個點爲根的子樹的路徑都會被割斷,而排序保證在同一子樹內部的路徑已經被處理過了,子樹信息能夠用dfs序來表示,區間操做能夠用左右端點打標記,用樹狀數組維護便可。c++

#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;
    }
相關文章
相關標籤/搜索