樹網的核 有關樹的直徑

2021-08-29 04:13:01 字數 1635 閱讀 4562

輸入樣例#1:

5 2

1 2 5

2 3 2

2 4 4

2 5 3

輸出樣例#1:

5
輸入樣例#2:

8 6

1 3 2

2 3 2

3 4 6

4 5 3

4 6 4

4 7 2

7 8 3

輸出樣例#2:

5
n<=500000

分析為了方便,st,ed表示直徑兩端的兩個點

首先來看樹的核是乙個點的情況

證明: 使偏心距最大的點一定是st或ed

若x的偏心距最大,那麼直徑應該就是x--ed了

同理,當核是一條路徑時,x上頭和y下頭的所有點都是不行的,所以這種情況的偏心距應該為

max(x到st的距離,y到ed的距離,(x,y)之間任意乙個節點到以該節點為根的最遠距離

因此我們先dfs出st,然後再dfs出到dis的距離已經ed

然後乙個乙個往上找s個長度(x,y) 然後更新答案,最後再dfs出直徑上的點到自己子樹的最大距離然後更新答案

#include#define n 100005

using namespace std;

int first[n],next[n*2],to[n*2],w[n*2],tot;

int n,s,st,ed,ans=0x3fffffff,vis[n];

int dep[n],fa[n],dis[n],dis_st[n],fa_st[n];

int read()

void add(int x,int y,int z)

void dfs(int u)

}void dfs_st(int u,int f)

}int main()

dep[1]=1,dfs(1);

dfs_st(st,0);

memcpy(dis,dis_st,sizeof(dis_st));

memcpy(fa,fa_st,sizeof(fa_st));

memset(vis,0,sizeof(vis));

for(int x=ed,y=ed;x!=0;x=fa[x])

for(int i=ed;i;i=fa[i]) dis[i]=0,dfs(i);

for(int i=1;i<=n;i++) ans=max(ans,dis[i]);

cout<

}

洛谷 P1099 樹網的核(樹的直徑 貪心)

用兩邊dfs求出直徑,用f記錄fa,這樣就記錄下了直徑的路徑,將直徑上的點vis標記為1。然後列舉左右端點 或者尺取法,但不會 貪心考慮對答案的貢獻 假設直徑的兩個端點為a和b,當前左右端點為i,j,對答案的貢獻只有a,i之間的距離 b,j之間的距離 i,j中每個節點的子樹的最遠距離。那麼可以對於直...

洛谷 P1099 樹網的核(樹的直徑,樹上尺取)

感覺課件裡講的還是比較詳細的。先說一下n 3做法 floyd預處理出樹中任意兩點之間的距離,然後在直徑上暴力列舉核的左右端點,再列舉每個點,則這個點到核的距離為 dis d i k dis d j k dis d i d j 2。畫圖即可推出來。o n 3 做法原題穩過,但是我們追求更高效的做法。o...

O N 的我不會 樹網的核

題目描述 設t v,e,w 是乙個無圈且連通的無向圖 也稱為無根樹 每條邊帶有正整數的權,我們稱t為樹網 treenetwork 其中v,e分別表示結點與邊的集合,w表示各邊長度的集合,並設t有n個結點。路徑 樹網中任何兩結點a,b都存在唯一的一條簡單路徑,用d a,b 表示以a,b為端點的路徑的長...