氪金帶東(樹任意一點到其他點的最遠距離 樹的直徑)

2021-10-23 03:22:47 字數 1865 閱讀 5785

輸入檔案包含多組測試資料。對於每組測試資料,第一行乙個整數n (n<=10000),接下來有n-1行,每一行兩個數,對於第i行的兩個數,它們表示與i號電腦連線的電腦編號以及它們之間網線的長度。網線的總長度不會超過10^9,每個數之間用乙個空格隔開。

對於每組測試資料輸出n行,第i行表示i號電腦的答案 (1<=i<=n).

51 1

2 13 1

1 1323

44去掉複雜的題幹,問題其實就是求樹上任意點到其他點的最遠距離。求解的方法有很多,充分利用樹的結構特點,利用樹的直徑。

• 首先回憶一下求樹的直徑的方法

• 假設樹的最長路的兩個葉子節點為v1, v2,從任意一點 u 出發走到的最遠的點一定是(v1,v2)中的一點,然後再從 v1 或者 v2 出發走到的最遠點一定是 v2 或者 v1。由此經過兩次遍歷就能找到最長路徑。

• 這道題不是找最長路徑,是找某個節點 x 所能到達的最長路徑。首先這個節點 x 的最長路徑要麼是到 v1 的路徑,要麼就是到 v2 的路徑。

• 由於不知道往哪邊走才是最長的路徑,所以需要分別從 v1, v2 點再次遍歷共需要三次遍歷。

• 這個題也可以使用樹形動態規劃來解決。

(剛開始一直wa,注意有多組測試資料!!!)參考**如下:

#include

#include

using

namespace std;

struct edge

}a[20010];

int vis[

10010

],vis1[

10010];

int t[

10010];

void

dfs(

int x,

int d)

void

dfs1

(int x,

int d)

intmain()

sort

(a,a+

2*n-2)

; t[1]

=0;t[n+1]

=2*n-2

;for

(int i=

1;i;i++)if

(a[i]

.x!=a[i-1]

.x)t[a[i]

.x]=i;

//求直徑的兩個端點x,y

for(

int i=

1;i<=n;i++

)vis[i]=-

1;dfs(1,

0); x=1;

for(

int i=

2;i<=n;i++)if

(vis[i]

>vis[x]

)x=i;

for(

int i=

1;i<=n;i++

)vis[i]=-

1;dfs(x,0)

; y=1;

for(

int i=

2;i<=n;i++)if

(vis[i]

>vis[y]

)y=i;

for(

int i=

1;i<=n;i++

)vis1[i]=-

1;dfs1

(y,0);

//最用距離為到直徑端點距離的最大值

for(

int i=

1;i<=n;i++)if

(vis1[i]

)printf

("%d\n"

,vis[i]);

else

printf

("%d\n"

,vis1[i]);

}return0;

}

Dijkstra演算法 求一點到任意一點的最短距離)

思路 先找出最短的乙個點,也就是起點,從起點出發,找最短的邊,同時標記起點為true 代表已經訪問過 訪問過的點就不用再訪問了,依次下去,保證每一次找到的邊都是最短的邊 到最後沒有邊可以更新了就代表結束 看 include include include include include includ...

直線外一點到直線的距離

已知直線上兩點求直線的一般式方程 已知直線上的兩點p1 x1,y1 p2 x2,y2 p1 p2兩點不重合。則直線的一般式方程ax by c 0中,a b c分別等於 a y2 y1 b x1 x2 c x2y1 x1y2 直線外一點到直線的距離 p 的座標為 xo,yo 則點 p 到直線 l 的距...

求一顆樹以任意點為根,其他點到根的和

思路 一遍 dfs 可以求到以任意乙個點為根,所有點所含孩子的個數,cnt陣列記錄 考慮每一條邊的貢獻時,即此邊左右節點數相乘 第2遍 dfs,以其他點為根時,例如以2為根,先去掉 0 1 邊的貢獻,再加上以2為根 0和1 對 2 的貢獻 示例 class solution cnt x sum vo...