P4281 AHOI2008 緊急集合 聚會

2022-04-10 03:57:10 字數 1519 閱讀 1496

題意描述:

link

歡樂島上有個非常好玩的遊戲,叫做「緊急集合」。在島上分散有 \(n\) 個等待點,有 \(n−1\) 條道路連線著它們,每一條道路都連線某兩個等待點,且通過這些道路可以走遍所有的等待點,通過道路從乙個點到另乙個點要花費乙個遊戲幣。

參加遊戲的人三人一組,開始的時候,所有人員均任意分散在各個等待點上(每個點同時允許多個人等待),每個人均帶有足夠多的遊戲幣(用於支付使用道路的花費)、地圖(標明等待點之間道路連線的情況)以及對話機(用於和同組的成員聯絡)。當集合號吹響後,每組成員之間迅速聯絡,了解到自己組所有成員所在的等待點後,迅速在 \(n\) 個等待點中確定乙個集結點,組內所有成員將在該集合點集合,集合所用花費最少的組將是遊戲的贏家。

小可可和他的朋友邀請你一起參加這個遊戲,由你來選擇集合點,聰明的你能夠完成這個任務,幫助小可可贏得遊戲嗎?

最近公共祖先 水題。

一句話題意,讓你找到乙個點使得給出的三個點到這個點的距離盡可能的小。

手玩樣例可以發現,他只會是任意兩點之間的最近公共祖先,就直接列舉一下就行。

具體證明的話,就是說這樣會使重複的路徑盡可能的少。 (bushi).

好像還有一種 \(o(1)\) 的做法,主要是我沒看懂。

但樹剖常數小, \(5e5\) 的資料跑的沒有問題。

code:

#include#include#includeusing namespace std;

const int n = 5e5+10;

int n,m,u,v,x,y,z,ans,id,tot;

int dep[n],siz[n],son[n],top[n],head[n],fa[n];

struct node

e[n<<1];

inline int read()

while(ch >= '0' && ch <= '9')

return s * w;

}void add(int x,int y)

void get_tree(int x)

}void dfs(int x,int topp)

}int lca(int x,int y)

return dep[x] <= dep[y] ? x : y;

}int dis(int x,int y)

int main()

get_tree(1); dfs(1,1);

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

lca = lca(x,z);

a = dis(x,lca), b = dis(y,lca), c = dis(z,lca);

if(ans > a+b+c)

lca = lca(y,z);

a = dis(x,lca), b = dis(y,lca), c = dis(z,lca);

if(ans > a+b+c)

printf("%d %d\n",id,ans);

} return 0;

}

P4281 AHOI2008 緊急集合 聚會

給定一棵樹,邊權為 1 多次詢問,給出三個點 a,b,c 求三個點的中點和到中點的總距離 定義中點為 x 滿足 dis a,x dis b,x dis c,x 最小 除錯日誌 jump 陣列開小,只開了 19 首先是樹上兩點距離 dis x,y dep x dep y 2 dep lca x,y 根...

AHOI2008 緊急集合 LCA

題目大意 給一棵樹,求三點之間最短距離,並求最短距離所在的點。題解 求出兩兩之間的lca,觀察可以發現,有兩個lca是相同的,且這個點一定在所有lca中深度最淺。畫乙個圖可以發現,集合點就是另乙個lca,因為這個點是這三個點互相路徑連線起來的公共點。至於距離,找個例子可以發現距離是dep a dep...

AHOI2008 緊急集合 聚會

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