【題解】
顯然的這是一道樹形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行每行包含兩個...