這個題目僅僅是因為我找了半天也沒找到這個神奇題目的名字而瞎起了乙個,題目過於簡單,題意過於明了,簡直像是某信奧書上講解樹形dp知識點用的模板。就這麼令人無語。
給出乙個n個點的樹,找出乙個點來,以這個點為根的樹時,所有點的深度之和最大
input
給出乙個數字n,代表有n個點.n<=1000000 下面n-1條邊.
output
輸出你所找到的點,如果具有多個解,請輸出編號最小的那個.
sample input
8 1 4
5 6
4 5
6 7
6 8
2 4
3 4sample output
7看了第一遍:這題簡單過了吧,直接白給。不會有什麼陷阱吧……
看了第二遍:沒有,真就白給。
既然每個點都可能是根節點,那我先找個1號節點算算試試。下面這是以1為根的樣例。下面是以5為根的圖,後面要用。
顯然f[1]=18。
那麼假如我把根節點換了呢?比如換成5號。
對於5號節點的子樹(包括自己),由於離根節點更近了一步,所以每節點的深度都要減一,而對於除了5的子樹之外的節點,由於離根節點遠了一步,深度都要加一,這樣的話f [5] = f [1] - 1 * size [5] + 1 * ( n -size [5] )。
同理,5的兒子也可以這麼推下去。那麼,我們得到乙個通式:
f [兒子] = f [父親] - 1 * size [兒子] + 1 * ( n -size [兒子] )
這樣的話,我們跑兩遍dfs,第一遍求f[1]和各個點的size,第二遍跑通式,求出最大值即可。
p.s. 如果非要說什麼易錯點,就是要開long long。最壞的情況就是點最多且排成一條鏈,這時深度和=(0+999999)*1000000/2=499999500000超int了。
p.s.s. 最開始我還糾結了許久根節點深度是1還是0最後發現好像無所謂……
p.s.s.s. 顯然p.s.裡面的最大值是按根節點深度為0算的。
1 #include2view codeusing
namespace
std;
3const
int maxn=1000000+5
;4 typedef long
long
ll;5
inthead[maxn],ans,size[maxn],n,tot;
6ll f[maxn],max;
7struct
nodee[2*maxn];
10void add(int a,int
b)16
void dfs1(int x,int fa,int
dep)25}
26void dfs2(int x,int
fa)35
if(f[v]==max&&vv;
36dfs2(v,x);37}
38}39int
main()
48 dfs1(1,0,0
);49 max=f[1]; ans=1
;50 dfs2(1,0
);51 printf("%d"
,ans);
52return0;
53 }
幸甚至哉,歌以詠志。
某科學的間斷超電磁炮
時間限制 1000 ms 記憶體限制 65535 k 問題描述 炮姐bilibili為了練習自己的能力,於是左右開弓開始shoot 開始的時候電磁炮應該是間斷的,所以打到的靶子也是不連續的。比如左手能打到1號 2號 3號靶子,右手能達到1 2 3 4 5號靶子。雖然她想知道自己到底打到了哪些靶子很容...
HAUT校賽 某科學的打麻將
時間限制 1 秒 記憶體限制 64 mb 提交 18 解決 2 提交狀態 題目描述 過年打麻將果然是一項必備技能 霧 打麻將的起手式是整理好自己手中的牌,現在你有十三張牌 只可能出現一萬到九萬,一筒到九筒,一條到九條 你要把這些牌整理好,使得相同花色的牌必須在連續的唯一一段 即所有的 萬 要放在一起...
河工大校賽E 某科學的打麻將
時間限制 1 秒 記憶體限制 64 mb 提交 74 解決 11 提交 狀態 題目描述 過年打麻將果然是一項必備技能 霧 打麻將的起手式是整理好自己手中的牌,現在你有十三張牌 只可能出現一萬到九萬,一筒到九筒,一條到九條 你要把這些牌整理好,使得相同花色的牌必須在連續的唯一一段 即所有的 萬 要放在...