Jzoj3906 魏傳之長阪逆襲(夢回三國系列)

2022-05-09 17:20:35 字數 1630 閱讀 5775

【題目背景】

眾所周知,劉備在長阪坡上與他的一眾將領各種開掛,硬生生從曹操手中逃了出去,隨後與孫權一**燒赤壁、占有荊益、成就霸業。而曹操則在赤壁一敗後再起不能,終生無力南下。

建安二十五年(220年),曹操已到風燭殘年,但仍難忘當年長阪的失誤,霸業的破滅。他想如果在劉備逃亡的路中事先布下一些陷阱,便能拖延劉備的逃脫時間了。你作為曹操身邊的太傅,有幸穿越到了208年的長阪坡,為大魏帝國貢獻乙份力,布置一些陷阱。但時空守衛者告訴你你不能改變歷史,不能拖增大劉備的最大逃脫時間,但你身為魏武之仕,忠心報國,希望能新增一些陷阱使得劉備不論怎麼逃跑所用的時間都一樣。

【問題描述】

已知共有n個據點,n-1條棧道,保證據點聯通。1號據點為劉備軍逃跑的起點,當劉備軍跑到某個據點後不能再前進時視為劉備軍逃跑結束。在任意乙個棧道上放置1個陷阱會使通過它的時間+1,且你可以在任意乙個棧道上放置任意數量的陷阱。

現在問你在不改變劉備軍當前最大逃跑時間的前提下,需要新增最少陷阱,使得劉備軍的所有逃脫時間都盡量的大。

其實就是讓你調整一些樹邊的邊權,使得根到每個葉子結點的路徑一樣長

我們令d[i]為i到根的距離,mg[i]為i的子樹中d的最大值,那麼顯然可以用一次dfs求出,讓後做一次dp即可:我們每次將點x的權值加上mg[1]-mg[x]-k,讓後遞迴下去,這相當於乙個貪心的過程

#include

#include

#include

#define n 500010

using

namespace

std;

struct edge g[n<<1];

int h[n],f[n],sz[n],n,m,cnt=0,r; long

long a=0,mg[n],d[n];

inline

void adj(int x,int y,int c); h[x]=cnt; }

void dfs(int x,int p)

}void dp(int x,int k)

int main()

dfs(1,0); r=mg[1];

for(int i=h[1];i;i=g[i].nt)

dp(g[i].v,0);

printf("%lld\n",a);

}

結果我們發現可以優化,其實答案就是σmg[f[i]]-mg[i]

#include

#include

#include

#define n 500010

using

namespace

std;

struct edge g[n<<1];

int h[n],f[n],sz[n],n,m,cnt=0,r; long

long a=0,mg[n],d[n];

inline

void adj(int x,int y,int c); h[x]=cnt; }

void dfs(int x,int p)

}int main()

dfs(1,0); r=mg[1];

for(int i=2;i<=n;++i) a+=mg[f[i]]-mg[i];

printf("%lld\n",a);

}

DX3906上的綠皮郵箱

花 好久未與你聯絡,不知你近況如何,也許你這時正與別人嗑著瓜子,聊著天呢,而我呢,正在看著書,聽著 今天心裡突然有個衝動,想給你寫一封信。這段時間會偶爾想起你,說來也奇怪哈,有你的名字,但是你的模樣我卻記不清楚了,只有名字,很奇怪吧,我也覺得奇怪,像魯迅寫 的那樣 腦袋裡憋出了兩個字 吃人 而我腦袋...

JZOJ 交換 模擬

給出字串s和字串t,現在你要把s的某乙個字元和t的某乙個字元交換,使得交換之後的s至少要有三個連續相同的字元,交換之後的t也要有三個連續相同的字元。問有多少種不同的交換方式。第一行,乙個字串s。s只含有 r g b 三種字元,長度不超過50,不小於3。而且s任意兩個相鄰的字元都不相同。第二行,乙個字...

JZOJ 規律 遊戲

有一堆金塊,king和貓老大輪流抽金塊,每次抽的個數必然是2的次方冪,求勝利 抽走最後一塊 的是誰 三行每行乙個數 n 0對於每局,如果 king 必勝則輸出一行 king will win.否則第一行輸出 maolaoda willwin.第二行輸出他第一次拿的最小數量。8 42maolaoda ...