[BZOJ 1787 & 1832] [Ahoi2008] Meet 紧急集合
1787 & 1832: [Ahoi2008]Meet 紧急集合
Time Limit: 10 Sec / 20 SecDescription
Input
Output
Sample Input
6 4
1 2
2 3
2 4
4 5
5 6
4 5 6
6 3 1
2 4 4
6 6 6
1 2
2 3
2 4
4 5
5 6
4 5 6
6 3 1
2 4 4
6 6 6
Sample Output
5 2
2 5
4 1
6 0
HINT
Source
【题解】
可以证明,最小的点一定在三点中任意两点的LCA上,那么只要用倍增来求下LCA即可。
注意,本题树根节点在1,因为你不知道父亲孩子的关系所以需要建两条边,BFS加一个判断就好
1 #include <bits/stdc++.h> 2 using namespace std; 3 int to[1000010],next[1000010],dep[1000010]; 4 int p[500010][21],n,m,head[500010],root,tot=0; 5 bool deg[500010]; 6 inline void bfs(int root) { 7 queue<int> Q; 8 p[root][0]=root; dep[root]=0; 9 Q.push(root); 10 while(!Q.empty()) { 11 int u=Q.front();Q.pop(); 12 for (int i=1;i<=20;++i) p[u][i]=p[p[u][i-1]][i-1]; 13 for (int i=head[u];i!=-1;i=next[i]) 14 if(to[i]!=p[u][0]) { 15 int v=to[i]; 16 dep[v]=dep[u]+1; p[v][0]=u; 17 Q.push(v); 18 } 19 } 20 } 21 inline int lca(int x,int y) { 22 if(dep[x]<dep[y]) {int t=x;x=y;y=t;} 23 for (int i=20;i>=0;--i) if((dep[x]-dep[y]) & (1<<i)) x=p[x][i]; 24 if(x==y) return x; 25 for (int i=20;i>=0;--i) 26 if(p[x][i]!=p[y][i]) 27 x=p[x][i],y=p[y][i]; 28 return p[x][0]; 29 } 30 inline int getdist(int u,int v) { 31 return dep[u]+dep[v]-(dep[lca(u,v)]<<1); 32 } 33 int main() { 34 memset(head,-1,sizeof(head)); 35 memset(deg,0,sizeof(deg)); 36 scanf("%d%d",&n,&m); 37 for (int i=1;i<=n-1;++i) { 38 int u,v; 39 scanf("%d%d",&u,&v); 40 to[tot]=v; 41 next[tot]=head[u]; 42 head[u]=tot++; 43 int t=u;u=v;v=t; 44 to[tot]=v; 45 next[tot]=head[u]; 46 head[u]=tot++; 47 } 48 bfs(1); 49 int a1,a2,a3,b1,b2,b3,u,v,w; 50 while(m--) { 51 scanf("%d%d%d",&u,&v,&w); 52 a1=lca(u,v); b1=dep[u]+dep[v]-(dep[a1]<<1)+getdist(a1,w); 53 a2=lca(u,w); b2=dep[u]+dep[w]-(dep[a2]<<1)+getdist(a2,v); 54 a3=lca(v,w); b3=dep[v]+dep[w]-(dep[a3]<<1)+getdist(a3,u); 55 //printf(" %d %d\n",a1,b1);printf(" %d %d\n",a2,b2);printf(" %d %d\n",a3,b3); 56 if(b1<b2) { 57 if(b1<b3) printf("%d %d\n",a1,b1); 58 else printf("%d %d\n",a3,b3); 59 } else { 60 if (b2<b3)printf("%d %d\n",a2,b2); 61 else printf("%d %d\n",a3,b3); 62 } 63 } 64 }
计算距离的时候只需要dep[x]+dep[y]-dep[lca(x,y)]*2就好了。
BZOJ 26题了好开心WWW
这篇文章由TonyFang发布。
所有解释权归TonyFang所有。
Mailto: tony-fang@map-le.net