AHOI2008 緊急集合 聚會

2022-05-16 12:10:32 字數 1635 閱讀 1246

緊急集合 / 聚會

題目大意:

給出乙個無向圖,每一次給出圖中的三個點,求離三個點距離之和最小的點。

解決方法:

倍增lca。

首先我們兩兩點之間求出lca,那麼離他們距離之和最近的點就是三個點中深度最深的點,想一想為什麼?

我們假設存在乙個點離三個點距離之和更近且深度更淺,那麼我們將它的深度往下走乙個,一定會有兩個點距離-1,乙個點+1,所以往下移更靠近正解opt,那麼我們就可以得出我們上述結論合法。

而關於距離之和,由於dis(u,v)=dep[u]+dep[v]-dep[lca(u,v)],那麼我們把三個點兩兩之間∑一下再除以二就能得到答案了,式子就不推了。。。

dis=dep[x]+dep[y]+dep[z]-dep[lca(x,y)]-dis[lca(y,z)]-dis[lca(x,z)]

最後附上本題**:

1 #include2 #include3

#define maxn 500000

4using

namespace

std;56

intn,m,root,cnt;

7int head[maxn+5],dep[maxn+5],f[maxn+5][30];8

bool vis[maxn+5];9

struct

edge10;

13 edge edge[maxn*2+5

];14

15int max(int x,int

y)16

21return

y;22}23

int abs(int

x)24

29return

x;30}31

void add(int x,int

y)32

37void pre_fir(int u,int

fa)38

44for(int i=head[u];i;i=edge[i].nxt)

4550 f[edge[i].to][0]=u;

51pre_fir(edge[i].to,u);52}

53}54int lca(int x,int

y)55

60for(int i=25;i>=0;i--)

6166

if(x==y)

6770}71

for(int i=25;i>=0;i--)

7278}79

return f[x][0

];80}81

intmain()

8292

for(int i=1;i<=n;i++)

9399

}100 dep[root]=1

;101 pre_fir(root,0

);102

for(int i=1;i<=m;i++)

103110

return0;

111 }

AHOI2008 緊急集合 聚會

歡樂島上有個非常好玩的遊戲,叫做 緊急集合 在島上分散有n個等待點,有n 1條道路連線著它們,每一條道路都連線某兩個等待點,且通過這些道路可以走遍所有的等待點,通過道路從乙個點到另乙個點要花費乙個遊戲幣。參加遊戲的人三人一組,開始的時候,所有人員均任意分散在各個等待點上 每個點同時允許多個人等待 每...

AHOI2008 緊急集合 聚會

歡樂島上有個非常好玩的遊戲,叫做 緊急集合 在島上分散有n個等待點,有n 1條道路連線著它們,每一條道路都連線某兩個等待點,且通過這些道路可以走遍所有的等待點,通過道路從乙個點到另乙個點要花費乙個遊戲幣。參加遊戲的人三人一組,開始的時候,所有人員均任意分散在各個等待點上 每個點同時允許多個人等待 每...

AHOI2008 緊急集合 聚會

歡樂島上有個非常好玩的遊戲,叫做 緊急集合 在島上分散有n個等待點,有n 1條道路連線著它們,每一條道路都連線某兩個等待點,且通過這些道路可以走遍所有的等待點,通過道路從乙個點到另乙個點要花費乙個遊戲幣。參加遊戲的人三人一組,開始的時候,所有人員均任意分散在各個等待點上 每個點同時允許多個人等待 每...