HDU 6203 ping ping ping(在线倍增LCA+BIT)
生活随笔
收集整理的這篇文章主要介紹了
HDU 6203 ping ping ping(在线倍增LCA+BIT)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Description
給出一棵n+1n+1個節點的樹,要求破壞盡可能少的點使得所給mm對點對均不可互達
Input
第一行一整數nn,之后nn行每行兩個整數u,vu,v表示一條樹邊,然后輸入一整數mm,最后mm行每行兩個整數u,vu,v表示需要使得u,vu,v不可互達(3≤n≤104,1≤p≤5?104)(3≤n≤104,1≤p≤5?104)
Output
輸出需要刪去的最少點數
Sample Input
4
1 0
4 2
2 0
3 2
2
1 3
2 1
Sample Output
1
Solution
為使被刪掉的點盡可能起作用,對于一個點對要刪去影響最大的點,即其LCALCA,對每個點對求出其LCALCA,把查詢按點對LCALCA深度降序排,先處理LCALCA深度最深的點對,因為先處理其他點對不能解決該點對的問題,但是先解決該點對的問題可以順帶就解決了其他點對的問題,刪去LCALCA后,為了保留下刪除該點的影響,把以該點為根的子樹全部標記加一,這樣以來,對于后面的點對u,vu,v,如果uu或vv的標記非零,說明uu或vv的某個祖先被刪掉了,且這個被刪掉的祖先深度比u,vu,v的LCALCA深度深,也即當前點對不需要刪點已經被解決掉了,對子樹的更新操作求出dfsdfs序后用樹狀數組維護即可
Code
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<vector> #include<queue> #include<map> #include<set> #include<ctime> using namespace std; #define maxn 10005 #define maxm 50005 int n,m,p[maxn][15],dep[maxn],index,L[maxn],R[maxn]; vector<int>g[maxn]; void dfs(int u,int fa) {p[u][0]=fa;for(int i=1;i<15;i++)p[u][i]=p[p[u][i-1]][i-1];L[u]=++index;for(int i=0;i<g[u].size();i++){int v=g[u][i];if(v==fa)continue;dep[v]=dep[u]+1;dfs(v,u);}R[u]=index; } int lca(int a,int b) {int i,j;if(dep[a]<dep[b])swap(a,b);for(i=0;(1<<i)<=dep[a];i++);i--;for(j=i;j>=0;j--)if(dep[a]-(1<<j)>=dep[b])a=p[a][j];if(a==b) return a;for(j=i;j>=0;j--)if(p[a][j]&&p[a][j]!=p[b][j])a=p[a][j],b=p[b][j];return p[a][0]; } struct BIT {#define lowbit(x) (x&(-x))int b[maxn],n;void init(int _n){n=_n;for(int i=1;i<=n;i++)b[i]=0;}void update(int x,int v){while(x<=n){b[x]+=v;x+=lowbit(x);}}int query(int x){int ans=0;while(x){ans+=b[x];x-=lowbit(x);}return ans;} }bit; struct node {int u,v,t;bool operator<(const node&b)const{return dep[t]>dep[b.t];} }a[maxm]; int main() {while(~scanf("%d",&n)){n++;bit.init(n);for(int i=1;i<=n;i++)g[i].clear();memset(p,0,sizeof(p));for(int i=1;i<n;i++){int u,v;scanf("%d%d",&u,&v);u++,v++;g[u].push_back(v),g[v].push_back(u);}index=0;dep[1]=0;dfs(1,0);scanf("%d",&m);for(int i=0;i<m;i++){scanf("%d%d",&a[i].u,&a[i].v);a[i].u++,a[i].v++;a[i].t=lca(a[i].u,a[i].v);}sort(a,a+m);int ans=0;for(int i=0;i<m;i++){int u=a[i].u,v=a[i].v,t=a[i].t;int temp=bit.query(L[u])+bit.query(L[v]);if(!temp){ans++;bit.update(L[t],1),bit.update(R[t]+1,-1);}}printf("%d\n",ans);}return 0; }總結
以上是生活随笔為你收集整理的HDU 6203 ping ping ping(在线倍增LCA+BIT)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Google glass GDK - H
- 下一篇: win7共享虚拟wifi