AHOI2008 聚會 倍增

2021-07-23 08:23:50 字數 1848 閱讀 9846

bzoj

description

y島風景美麗宜人,氣候溫和,物產豐富。y島上有n個城市,有n-1條城市間的道路連線著它們。每一條道路都連線某兩個城市。幸運的是,小可可通過這些道路可以走遍y島的所有城市。神奇的是,乘車經過每條道路所需要的費用都是一樣的。小可可,小卡卡和小yy經常想聚會,每次聚會,他們都會選擇乙個城市,使得3個人到達這個城市的總費用最小。 由於他們計畫中還會有很多次聚會,每次都選擇乙個地點是很煩人的事情,所以他們決定把這件事情交給你來完成。他們會提供給你地圖以及若干次聚會前他們所處的位置,希望你為他們的每一次聚會選擇乙個合適的地點。

input

第一行兩個正整數,n和m。分別表示城市個數和聚會次數。後面有n-1行,每行用兩個正整數a和b表示編號為a和編號為b的城市之間有一條路。城市的編號是從1到n的。再後面有m行,每行用三個正整數表示一次聚會的情況:小可可所在的城市編號,小卡卡所在的城市編號以及小yy所在的城市編號。

output

一共有m行,每行兩個數pos和cost,用乙個空格隔開。表示第i次聚會的地點選擇在編號為pos的城市,總共的費用是經過cost條道路所花費的費用。

sample input

6 4

1 22 3

2 44 5

5 64 5 6

6 3 1

2 4 4

6 6 6

sample output

5 2

2 54 1

6 0

資料範圍:

100%的資料中,n<=500000,m<=500000。

40%的資料中n<=2000,m<=2000。

題解:

沒什麼特別好的思路,感覺我就是暴力。。。

嗯,就是把三個點兩兩的lca = t找出來,然後找出t與第三個點的lca,然後計算長度,嗯,三個長度都算出來了,之後比較三個長度的長短,輸出最短的。就算用的倍增找lca,而且思路感覺有點偷懶,最後還是成功ac,且在bzoj排在100名,還可以。

**:

#include 

#include

using namespace std;

const int maxn = 500005;

int n,m,maxd,e = 1;

int head[maxn],deep[maxn],anc[maxn][25];

inline int

abs(int

x)struct nodeedge[maxn*2];

inline void addedge(int u,int v);head[u] = e++;

edge[e] = (node);head[v] = e++;

}inline int

read()

while('0'

<= ch&& ch <='9')

returnx;}

inline void init()

}void dfs(int u,int h)

}}inline void swim(int &u,int h)

}inline int query(int u,int v)

if(u != v) return anc[u][0];

return u;

}int main()

else

}return

0;}

AHOI2008 緊急集合 聚會

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

AHOI2008 緊急集合 聚會

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

AHOI2008 緊急集合 聚會

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