CF 294 div2 E. A and B and Lecture Rooms (LCA)
2015-03-25 11:20
351 查看
题目:http://codeforces.com/contest/519/problem/E
题意:给n个点和n-1条边,点的编号为(1,2,....n)。给两个点a,b,然后询问有多少个点到a的距离和到b的距离相等,点的个数和询问次数<=105
分析:这里需要知道怎么求最近公共祖先LCA,倍增法求LCAhttp://www.tuicool.com/articles/N7jQV32
Tarjan算法求LCAhttp://noalgo.info/476.html.求出LCA和每个节点的深度后,就知道a到LCA的距离和b到LCA的距离,然后a到b的距离也就知道了。用倍增法求出a,b的中点,最后分情况讨论一下就行了。
代码:
题意:给n个点和n-1条边,点的编号为(1,2,....n)。给两个点a,b,然后询问有多少个点到a的距离和到b的距离相等,点的个数和询问次数<=105
分析:这里需要知道怎么求最近公共祖先LCA,倍增法求LCAhttp://www.tuicool.com/articles/N7jQV32
Tarjan算法求LCAhttp://noalgo.info/476.html.求出LCA和每个节点的深度后,就知道a到LCA的距离和b到LCA的距离,然后a到b的距离也就知道了。用倍增法求出a,b的中点,最后分情况讨论一下就行了。
代码:
#include <iostream> #include <cstdio> #include <vector> using namespace std; #define MAXN 1<<17 struct tree { vector <int > vt[MAXN]; int deep[MAXN],anc[MAXN][17],sz[MAXN]; void Clear(int n) { for(int i=0;i<=n;i++) { deep[i]=0; sz[i]=1; for(int j=0;j<=16;j++) anc[i][j]=1; } } void Creat(int x) { for(int i=0;i<vt[x].size();i++) { int temp=vt[x][i]; if(anc[x][0]!=temp) { anc[temp][0]=x; deep[temp]=deep[x]+1; for(int j=1;j<=16;j++) anc[temp][j]=anc[anc[temp][j-1]][j-1]; Creat(temp); sz[x]+=sz[temp]; } } } int jump(int x,int n) { for(int i=0;i<17;i++) if(n&(1<<i)) x=anc[x][i]; return x; } int LCA(int a,int b) { a=jump(a,deep[a]-deep[b]); if(a==b) return a; for(int i=16;i>=0;i--) { if(anc[a][i]!=anc[b][i]) { a=anc[a][i]; b=anc[b][i]; } } return anc[a][0]; } int solve(int &a,int &b,int N) { if(a==b) return N; if(deep[a]<deep[b]) swap(a,b); int lca=LCA(a,b),dis=deep[a]-deep[lca]+deep[b]-deep[lca]; int mida,midb,mid; if(dis&1) return 0; dis>>=1; if((mid=jump(a,dis))==lca) { mida=jump(a,dis-1); midb=jump(b,dis-1); return N-sz[mida]-sz[midb]; } else { mida=jump(a,dis-1); return sz[mid]-sz[mida]; } } void DEBUG(int x) { for(int i=1;i<=x;i++) { printf("deep %d:%d\n",i,deep[i]); } } }T; int main() { int n,N,a,b,lca,ans; scanf("%d",&n); N=n--; T.Clear(N); while(n--) { scanf("%d%d",&a,&b); T.vt[a].push_back(b); T.vt[b].push_back(a); } T.Creat(1); scanf("%d",&n); while(n--) { scanf("%d%d",&a,&b); ans=T.solve(a,b,N); printf("%d\n",ans); } return 0; }
相关文章推荐
- Codeforces Round #294 (Div. 2) E. A and B and Lecture Rooms(倍增LCA+树形DP)
- [CF Round #294 div2] E. A and B and Lecture Rooms 【树上倍增】
- Codeforces Round #294 (Div. 2)-E. A and B and Lecture Rooms(LCA倍增)
- 【LCA】 Codeforces Round #294 (Div. 2) E. A and B and Lecture Rooms
- Codeforces Round #294 (Div. 2) E. A and B and Lecture Rooms(lca+思维,树上寻找与给定两个点距离相等的点的个数)
- LCA好(Codeforces Round #294 (Div. 2)E. A and B and Lecture Rooms)
- 在线LCA 倍增法 Codeforces Round #294 (Div. 2) E - A and B and Lecture Rooms
- Codeforces Round #294 (Div. 2) A and B and Lecture Rooms(LCA 倍增)
- Codeforces 519E A and B and Lecture Rooms [倍增法LCA]
- Codeforces Round #294 (Div. 2)---E. A and B and Lecture Rooms
- #294 (div.2) E.A and B and Lecture Rooms
- [codefoces519E]A and B and Lecture Rooms(lca)
- [CodeForces519E]A and B and Lecture Rooms(lca)
- Codeforces Round #294 (Div. 2) E. A and B and Lecture Rooms
- CF 294 div2 D. A and B and Interesting Substrings (hash)
- Codeforces Round #294 (Div. 2)-E. A and B and Lecture Rooms
- [CF Round #294 div2] D. A and B and Interesting Substrings 【Map】
- CF(#294 div2):D. A and B and Interesting Substrings
- E. President and Roads (CF Round #Pi (Div. 2)) 优先队列的Dij+Tarjan找桥
- CF 305 div2 E. Mike and Foam (容斥原理)