日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HDU 6203 ping ping ping(在线倍增LCA+BIT)

發布時間:2024/3/26 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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不可互達(3n104,1p5?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,如果uuvv的標記非零,說明uuvv的某個祖先被刪掉了,且這個被刪掉的祖先深度比u,vu,vLCALCA深度深,也即當前點對不需要刪點已經被解決掉了,對子樹的更新操作求出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)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。