緊急集合 / 聚會
題目大意:
給出乙個無向圖,每一次給出圖中的三個點,求離三個點距離之和最小的點。
解決方法:
倍增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條道路連線著它們,每一條道路都連線某兩個等待點,且通過這些道路可以走遍所有的等待點,通過道路從乙個點到另乙個點要花費乙個遊戲幣。參加遊戲的人三人一組,開始的時候,所有人員均任意分散在各個等待點上 每個點同時允許多個人等待 每...