題目鏈結
題意:給你一棵n個點的樹,有m個點對,你要在樹上找乙個點x,使得對於所有的點對(u,v),dis(x,u)+dis(x,v)最小,輸出這個最小值。n,m<=100000
題解:感覺之前點分治學得不好,所以最近想補一下。
這個題其實拿到題想過點分治,但是好像並不滿足分治常見的子問題結構,就沒想好怎麼處理。看了題解之後覺得還是挺妙的。
首先我們考慮暴力的話是列舉每乙個點,然後以這個點為根dfs一遍,就可以求出這個點到所有點的距離,然後再列舉點對算答案,複雜度是o(n
2+n∗
m)
o(n^2+n*m)
o(n2+n
∗m)。我們其實不難感覺到,如果我們現在知道了在某個位置的答案,只有很少的位置可能使答案繼續變小,我們考慮只去在這些可能讓答案變優的點dfs和對於點對算答案。
首先說一下什麼情況下可以確實當前點就是最優點。首先,以這個點為根,如果當前這個點在距離最長的點對的路徑上,也就是距離最長的點對位於這個點的不同子樹內,那麼答案一定不會比當前答案更優,原因是答案不管怎麼變,都不會比當前兩點之間的簡單路徑更短的情況了。然後如果有兩個及以上的最長路徑點對,並且這些點對中存在兩個點對在這個點的不同子樹裡,那麼答案也一定不會變小了,因為你再往別的地方走頂多是乙個變小乙個變大,在不同子樹是沒辦法同時變小的,而變大的那個將是你的結果,所有不會變優了。唯一需要繼續求的就是所有離當前點距離和最長的點對都在這個點的同乙個子樹裡,那麼我們需要到這個子樹裡去求。
但是我們發現乙個問題,如果樹是一條鏈,你直接這樣走到子節點再求一遍,複雜度還是不對的。我們考慮在這時候點分治,每次先確定該往當前點的哪個子樹走,再在這個子樹內找重心,在重心處重新dfs一遍並統計與所有點對的答案。根據點分治的性質,我們最多需要分治的層數是log
nlogn
logn
級別,所以我們只需要dfs並算m個點對的答案的點只有log
nlogn
logn
個,於是複雜度是o(n
logn
)o(nlogn)
o(nlog
n)。**:
#include
using
namespace std;
int n,m,u[
100010
],v[
100010
],hed[
100010
],fa[
100010
],dep[
100010];
int rt,sz[
100010
],mx[
100010
],vis[
100010
],ans,q[
100010
],cnt;
struct node
a[200010];
inline
intread()
return x;
}inline
void
add(
int from,
int to,
int dis)
inline
void
getrt
(int x,
int f,
int size)
mx[x]
=max
(mx[x]
,size-sz[x]);
if(mx[x]
) rt=x;
}inline
void
dfs(
int x,
int f,
int dis,
int g)
}inline
void
solve
(int x)
cnt=0;
int ji=0;
for(
int i=
1;i<=m;
++i)
else
if(dep[u[i]
]+dep[v[i]
]==ji)
q[++cnt]
=i;}
ans=
min(ans,ji)
; ji=0;
for(
int i=
1;i<=cnt;
++i)
} rt=0;
getrt
(ji,x,sz[ji]);
solve
(rt);}
intmain()
for(
int i=
1;i<=m;
++i)
mx[0]
=2e9
; ans=
2e9;
getrt(1
,0,n);
solve
(rt)
;printf
("%d\n"
,ans)
;return0;
}
luogub P4886 快遞員(點分治)
記得是9月月賽題,當時做的時候覺得跟zjoi2015幻想鄉戰略遊戲那道題很像?就寫了,然後就寫掛了。我們發現假設當前點為根,我們算出 m 次詢問中最遠的 a 對點,如果這 a 對點,全部都兩個點在根的不同子樹中。當前點就是最優的就是答案。當全部 a 對點都在乙個子樹中,我們把答案改為那個子樹對應的兒...
題解 洛谷 P4886 快遞員
考慮乙個節點成為根節點後,如何判斷其為最優的。若最長距離的路徑中的任意一條滿足兩個端點在當前根節點的兩個不同的兒子中,則當前根節點為最優的。因為若將其調整為不在該路徑上的點,最長路徑的值會變大,將其調整為該路徑上別的點,可能會產生更長的路徑,因此該根節點為最優的。若存在兩條最長距離的路徑的端點不來自...
遞迴 重心 Luogu P4886 快遞員
bob 的城市裡有 nn 個郵遞站,由於經濟考慮,這些郵遞站被 n 1n 1 條帶權無向邊相連。即 這 nn 個郵遞站構成了一棵樹。bob 正在應聘乙個快遞員的工作,他需要送 mm 個商品,第 ii 個商品需要從 uu 送到 vv。由於 bob 不能帶著商品走太長的路,所以對於一次送貨,他需要先從快...