三中校內訓練 旅行

2022-06-03 08:00:12 字數 1753 閱讀 7211

【題解】

顯然的這是一道樹形dp的題目

這裡令f[i][0]為從i出發向以它為根的子樹裡走直到不能走的最大、最小價值

(不能走是什麼自己閱讀題目)

令s為x的兒子,w[i][j]為i和j之間的邊的長度,則

f[x][0]=max(f[s][1]+w[s][i])

f[x][1]=min(f[s][0]+w[s][i])

顯然的通過這種方法,我們可以得到60分

可是,如何優化到線性呢

我們考慮乙個節點x,x向某條邊走的情況出現了很多次,浪費了很多時間

我們定義h[x][0/1]為從x出發,經過x的父親fa走到不能走為止的最大、最小價值

顯然的h[x][0]會被x的兄弟節點y的f[y][1]和h[fa][1]影響,

h[x][1]會被x的兄弟節點y的f[y][0]和x父親fa的h[fa][0]影響,

我們要從中選取乙個最大的或者最小的計入答案

但是為了防止被自己這顆子樹更新,我們需要求乙個次小和次大

以x為根的樹的答案可以順便處理,具體看**

#include#include

#include

#define mod 1000000007

#define il inline

using

namespace

std;

const

int n=1000001

;typedef

long

long

ll;struct edge e[n];

intn,m,g[n];

ll f[n][

2],p[n][2

],ans[n];

il void addedge(int x,int y,int

z);g[x]=m;

}il

void dfs1(int h,int

fa)

if(f[h][1]==(1ll<<50)) f[h][1]=0;}

il void dfs2(int h,int

fa)

else

if(x>l2) l2=x;

if(yy;}

else

if(yy;

}if(h>1

)

else

if(p[h][0]>l2) l2=p[h][0

];

if(p[h][1]1

];}

else

if(p[h][1]1

]; }

for(int i=g[h];i;i=e[i].next)

ans[h]=l1;

}int

main()

dfs1(

1,0);dfs2(1,0

);

for(int i=1;i<=n;i++) printf("

%lld\n

",ans[i]);

return0;

}

《人性的弱點》(三)中

3.勇於承認自己的錯誤 規則3 如果你錯了,就請迅速並坦然地承認它。無論什麼時候,如果我們知道自己即將受到指責,那麼我們先發制人 自己首先承認不是更好嗎?比起承受別人的指責,自己主動承認錯誤不是更加容易接受嗎?把別人心裡想的,並想對你說的,或者打算對你說的那些指責發難的話,先發制人,自己先說出來。百...

類的三中方法

在類裡可以定義三種方法 1,例項方法 方法的第乙個引數是self 2,類方法 方法的第乙個引數是cls 表示當前類 需要帽子 classmethod 3,靜態方法 方法沒有引數,帶有帽子 staticmethod class person object country 中國 skin color 黃...

11 1二中校內模擬賽T1 trie樹 遞迴

玩具裝箱 eirt.cpp c pas 問題描述 你有兩堆物品分別有n1,n2個,每個物品有兩個屬性ai,bi。你要從兩堆中分別選乙個物品,滿足a1 a2 m 表示異或 的前提下最大化b1 b2。輸入格式 輸入檔名為eirt.in。第一行包含 3 個整數 n1,n2,m。接下來的 n1行每行包含兩個...