問題描述
何老闆最近在玩一款追鋪遊戲,遊戲雖然簡單,何老闆仍舊樂此不疲。輸入格式遊戲地圖中有n座城市由n-1條雙向道路連線。任意兩座城市都可相互到達。一名罪犯從a城市出發沿最短路線逃往b城市。在罪犯出發的同時,何老闆控制一名警察從c城市出發去追捕那名罪犯。每條道路都有一定的長度(單位公尺)。罪犯和警察行走的速度相同,都是1秒鐘行走1公尺。
若罪犯到達b城市時還沒有被抓住,何老闆就輸掉了這局遊戲。何老闆總共玩了m局遊戲,每局遊戲開始前,何老闆想知道他是否能贏下這局遊戲,如果能,警察最少行走多少公尺才能抓到罪犯?
第一行,兩個整數n和m輸出格式接下來n-1行,每行三個整數x,y,z,表示城市x和y之間有一條長度為z的道路相連。
接下來m行,每行三個整數a,b,c。
m行,每行對應一局遊戲的結果。若能抓捕到罪犯。輸出乙個整數,表示警察最少需要行走的距離。若無法抓到罪犯,輸出-1。樣例輸入
11 2樣例輸出1 2 6
1 3 3
1 4 3
3 5 2
3 6 5
4 7 9
6 10 3
5 8 4
5 9 3
8 11 8
11 9 10
2 4 7
10樣例解釋9
第1局在5號城市抓住罪犯。資料範圍第2局在4號城市抓住罪犯。
對於約40% 的資料:1<=n,m<=2000對於100% 的資料:1<=n,m<=100000 1<=道路的長度<=10000
由於樹的性質,兩點之間有且僅有一條路徑。因此當c不在a、b的的路徑上時,c要到a、b的路徑上,只有乙個唯一的點d進行中轉(否則就會有環)。也就是說,警察的路徑也是唯一的。那麼只需要比較警察和小偷到達d點的時間即可。
通常的想法是,先找出d的位置,再計算dis(a,d)和dis(c,d)。然而這樣實現起來比較麻煩。事實上,容易得到以下關係:
dis(a,d)=dis(a,c)+dis(a,b)-2*dis(b,c)
dis(c,d)=dis(a,c)+dis(b,c)-2*dis(a,b)
快速查詢樹上兩點的距離,倍增即可。
小小總結一下:#include
#define min(x,y) ((x#define maxm 200005
#define maxn 100005
int n,m,dis;
int en[maxm],las[maxn],nex[maxm],len[maxm],tot;
void add(int
x,int
y,int z)
int dep[maxn],fa[maxn][20],dis[maxn][20];
void dfs(int
x,int f,int z)
}int lca(int
x,int
y)int main()
dfs(1,0,0);
for(i=1;i<=m;i++)
}
樹上的一些問題,鑑於樹上兩點間有且僅有一條路徑,僅使用距離討論就可以簡單而方便的解決很多問題。
nkoj 4239 追捕遊戲
問題描述 何老闆最近在玩一款追鋪遊戲,遊戲雖然簡單,何老闆仍舊樂此不疲。遊戲地圖中有n座城市由n 1條雙向道路連線。任意兩座城市都可相互到達。一名罪犯從a城市出發沿最短路線逃往b城市。在罪犯出發的同時,何老闆控制一名警察從c城市出發去追捕那名罪犯。每條道路都有一定的長度 單位公尺 罪犯和警察行走的速...
GDOI2017 取石子遊戲 LCA
給出一棵樹,每個點都有乙個權值。對於每個節點,求去掉該節點的子樹後,剩下所有節點的權值mex 最小的沒有出現的非負整數。用權值線段樹合併亂搞顯然是可行的,但細節很多且需要卡常。我們考慮所有權值為 i 的節點對答案的影響。求所有節點的lca,那麼對於從lca向上到根的路徑上的節點,去掉子樹後的部分中一...
BZOJ3991 尋寶遊戲 LCA 虛樹 SET
小b最近正在玩乙個尋寶遊戲,這個遊戲的地圖中有n個村莊和n 1條道路,並且任何兩個村莊之間有且僅有一條路徑可達。遊戲開始時,玩家可以任意選擇乙個村莊,瞬間轉移到這個村莊,然後可以任意在地圖的道路上行走,若走到某個村莊中有寶物,則視為找到該村莊內的寶物,直到找到所有寶物並返回到最初轉移到的村莊為止。小...