JZOJ7月16日提高組T3 樹上路徑

2021-10-08 04:40:12 字數 1860 閱讀 6734

題解現在有一棵n個點的無向樹,每個點的編號在1-n之間,求出每個點所在的最長路。

輸入檔名為tree.in。

第一行為乙個整數n。

之後n-1行,每行三個整數u,v,w,分別表示一條邊連的兩個點和邊權。

輸出檔案tree.out,共n行,分別表示經過每個點的最長路。

41 2 3

1 3 4

1 4 277

76對於50%,1<=n<=1000

對於100%,1<=n<=100000,每個點的度不超過30,1<=u,v<=n,1<=w<=10000

題意:在一顆無向樹上找分別經過每個點的最長路徑

既然是要求每乙個數各自的最長路

那麼以每乙個數都作根來求是不現實的

所以需要固定乙個數為根(例如1)

我們先把每個節點到葉子節點的最長路和次長路給計算出來(注意,最長路和次長路不能有公共點,當前點除外)

則,對於每個點的兒子節點的答案

就有三種計算方法

其中,num是已經計算出來的

那麼上的三種路徑用文本來表達就是

1.父親的貢獻+當前節點到兒子節點的路徑長度+兒子節點的最長路

2.當前節點的最長路/次長路(在兒子節點位於當前的最長路上時)+當前節點到兒子節點的路徑長度+兒子節點的最長路

3.兒子節點的次長路+兒子節點的最長路

簡化一下就是:

設s

ss=父親的貢獻+當前節點到兒子節點的路徑長度、父親的最長路/次長路(在當前節點位於父親的最長路上時)+父親到當前節點的路徑長度、兒子節點的次長路中最長

那麼兒子節點的答案就是:s

ss+兒子節點的最長路

接下來思考:怎麼處理num

因為我們要處理的是兒子的兒子節點

那麼兒子節點的父親的貢獻就是當前節點的貢獻

也就是sss

#include

#include

using

namespace std;

int n,i,x,y,z,tot,f[

100005

],d[

100005

],l[

100005][

3];struct node

a[200005];

void

add(

int x,

int y,

int z)

void

dfs(

int now,

int fa)

else

if(l[now][2

].to][1

]+a[i]

.val) l[now][2

]=l[a[i]

.to][1

]+a[i]

.val;}}

void

count

(int now,

int sum)

else}}

intmain()

dfs(1,

0);count(1

,0);

d[1]=l[1]

[1]+l[1]

[2];

for(i=

1;i<=n;i++

)printf

("%d\n"

,d[i]);

return0;

}

JZOJ7月16日提高組T1 質數

題解定義質數為因數只含1和其本身的數,對於n組詢問,試判斷每個數是否為素數。第一行乙個正整數n,表示有n組詢問。接下來n行,每行乙個正整數m,表示詢問m是否為質數。輸出n行,每行乙個字串。若是質數則輸出 prime 若不是質數則輸出 not prime 52 1089807289 903248294...

JZOJ7月23日提高組T1 同餘

題解有一同餘方程 滿足p pp是質數,xi,jx xi,j 在0 p pp之間 問滿足同餘方程的方案數模乙個給出的數後的結果 手模資料或者打表可以發現,當c 0 c 0c 0時,所有答案都是一樣的 那麼就可以分成c 0 c 0c 0和c 0c 0 c 0兩種情況討論 轉移一下就好了 include ...

JZOJ7月25日提高組T1 挑竹籤

挑竹籤 小時候的遊戲 夏夜,早苗和諏訪子在月光下玩起了挑竹籤這一經典的遊戲。挑竹籤,就是在桌上擺上一把竹籤,每次從最上層挑走一根竹籤。如果動了其他的竹籤,就要換對手來挑。在所有的竹籤都被挑走之後,誰挑走的竹籤總數多,誰就勝了。身為神明的諏訪子自然會讓早苗先手。為了獲勝,早苗現在的問題是,在諏訪子出手...