【BZOJ 1832】 [AHOI2008]聚会|倍增lca
2016-04-23 08:31
337 查看
100ac 留念
双倍经验题
两两求距离 相加除以二为距离
两两求lca depth最大为三个的lca
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN=500000+10;
int to[MAXN][20],depth[MAXN];
int tot,g[MAXN],nnext[MAXN*2],num[MAXN*2] ;
int team[MAXN],head,tail;
void add(int x,int y)
{
tot++;
nnext[tot]=g[x];
g[x]=tot;
num[tot]=y;
}
void bfs()
{
depth[1]=1;
team[++tail]=1;
while(head<tail)
{
int x=team[++head];
for(int i=1;i<=19;i++) to[x][i]=to[to[x][i-1]][i-1];
for(int i=g[x];i;i=nnext[i])
{
int tmp=num[i];
if(tmp==to[x][0]) continue;
depth[tmp]=depth[x]+1;
to[tmp][0]=x;
team[++tail]=tmp;
}
}
}
int lca(int x,int y)
{
if(depth[x]<depth[y])swap(x,y);
for(int i=19;i>=0;i--)
if(depth[to[x][i]]>=depth[y])
x=to[x][i];
if(x==y) return x;
for(int i=19;i>=0;i--)
if(to[x][i]!=to[y][i])
x=to[x][i],y=to[y][i];
return to[x][0];
}
int dis(int x,int y,int fa)
{
return abs(depth[x]-depth[fa])+abs(depth[y]-depth[fa]);
}
int main()
{
int n,m;
int x,y,z;
scanf("%d %d",&n,&m);
for(int i=1;i<n;i++) scanf("%d %d",&x,&y),add(x,y),add(y,x);
bfs();
for(int i=1;i<=m;i++)
{
scanf("%d %d %d",&x,&y,&z);
int zx=lca(x,z);
int zy=lca(z,y);
int xy=lca(x,y);
int ans=zx;
if(depth[ans]<depth[zy]) ans=zy;
if(depth[ans]<depth[xy]) ans=xy;
int tmp1=dis(x,y,xy);
int tmp2=(dis(x,z,zx)+dis(z,y,zy)-tmp1)/2;
printf("%d %d\n",ans,tmp1+tmp2);
}
return 0;
}
双倍经验题
两两求距离 相加除以二为距离
两两求lca depth最大为三个的lca
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN=500000+10;
int to[MAXN][20],depth[MAXN];
int tot,g[MAXN],nnext[MAXN*2],num[MAXN*2] ;
int team[MAXN],head,tail;
void add(int x,int y)
{
tot++;
nnext[tot]=g[x];
g[x]=tot;
num[tot]=y;
}
void bfs()
{
depth[1]=1;
team[++tail]=1;
while(head<tail)
{
int x=team[++head];
for(int i=1;i<=19;i++) to[x][i]=to[to[x][i-1]][i-1];
for(int i=g[x];i;i=nnext[i])
{
int tmp=num[i];
if(tmp==to[x][0]) continue;
depth[tmp]=depth[x]+1;
to[tmp][0]=x;
team[++tail]=tmp;
}
}
}
int lca(int x,int y)
{
if(depth[x]<depth[y])swap(x,y);
for(int i=19;i>=0;i--)
if(depth[to[x][i]]>=depth[y])
x=to[x][i];
if(x==y) return x;
for(int i=19;i>=0;i--)
if(to[x][i]!=to[y][i])
x=to[x][i],y=to[y][i];
return to[x][0];
}
int dis(int x,int y,int fa)
{
return abs(depth[x]-depth[fa])+abs(depth[y]-depth[fa]);
}
int main()
{
int n,m;
int x,y,z;
scanf("%d %d",&n,&m);
for(int i=1;i<n;i++) scanf("%d %d",&x,&y),add(x,y),add(y,x);
bfs();
for(int i=1;i<=m;i++)
{
scanf("%d %d %d",&x,&y,&z);
int zx=lca(x,z);
int zy=lca(z,y);
int xy=lca(x,y);
int ans=zx;
if(depth[ans]<depth[zy]) ans=zy;
if(depth[ans]<depth[xy]) ans=xy;
int tmp1=dis(x,y,xy);
int tmp2=(dis(x,z,zx)+dis(z,y,zy)-tmp1)/2;
printf("%d %d\n",ans,tmp1+tmp2);
}
return 0;
}
相关文章推荐
- 印度储备银行行长批评央行,关注数字货币追赶中国
- FreeRTOS学习笔记
- Flex Library ANT 编译
- 歌词同步显示
- 第一冲刺阶段——站立会议第六天4月23日
- 第一冲刺阶段 工作总结 05
- ARP协议与RARP协议
- iOS-网络请求
- 【012】【Java晚期(运行期)优化】
- 保险业巨头John Hancock启动区块链技术试验
- 【bzoj1237】【scoi2008】【配对】【dp】
- 跋涉不止(45)
- Timer,TimerTask,TaskQueue,TimerThread原理关系图
- 河海大学常州校区第三届H-star程序设计大赛决赛
- poj 3311 Hie with the Pie floyd+状态压缩dp
- 跋涉不止(44)
- 支付服务公司Qiwi计划成立俄罗斯的R3CEV
- delphi7如何安装oracle access控件
- js相关转转文章
- 逻辑回归数学推倒讲解