消耗戰 dp 虛樹

2022-09-01 10:36:14 字數 2303 閱讀 1085

【題目描述】

在一場戰爭中,戰場由 $n$ 個島嶼和 $n-1$ 個橋梁組成,保證每兩個島嶼間有且僅有一條路徑可達。現在,我軍已經偵查到敵軍的總部在編號為 $1$ 的島嶼,而且他們已經沒有足夠多的能源維繫戰鬥,我軍勝利在望。已知在其他 $k$ 個島嶼上有豐富能源,為了防止敵軍獲取能源,我軍的任務是炸毀一些橋梁,使得敵軍不能到達任何能源豐富的島嶼。由於不同橋梁的材質和結構不同,所以炸毀不同的橋梁有不同的代價,我軍希望在滿足目標的同時使得總代價最小。

偵查部門還發現,敵軍有一台神秘機器。即使我軍切斷所有能源之後,他們也可以用那台機器。機器產生的效果不僅僅會修復所有我軍炸毀的橋梁,而且會重新隨機資源分布(但可以保證的是,資源不會分布到 $1$ 號島嶼上)。不過偵查部門還發現了這台機器只能夠使用 $m$ 次,所以我們只需要把每次任務完成即可。

【輸入格式】

第一行乙個整數 $n$ ,代表島嶼數量。

接下來 $n-1$ 行,每行三個整數 $u,v,w$ ,代表 $u$ 號島嶼和 $v$ 號島嶼由一條代價為 $c$ 的橋梁直接相連,保證 $1 \le u,v \le n$ 且 $1 \le c \le 100000 $ 。

第 $n+1$ 行,乙個整數 $m$ ,代表敵方機器能使用的次數。

接下來 $m$ 行,每行乙個整數 $k_i$ ,代表第 $i$ 次後,有 $k_i$ 個島嶼資源豐富,接下來 $k$ 個整數$h_1,h_2,…h_k$ ,表示資源豐富島嶼的編號。

【輸出格式】

輸出有 $m$ 行,分別代表每次任務的最小代價。

【樣例輸入】

101 5 13

1 9 6

2 1 19

2 4 8

2 3 91

5 6 8

7 5 4

7 8 31

10 7 9

32 10 6

4 5 7 8 3

3 9 4 6

【樣例輸出】

1232

22【資料範圍與提示】

對於100%的資料, $2 \le n \le 250000,m \ge 1, \sum \le 500000,1 \le k_i \le n-1 $

考慮樹形 dp,記 $ g[i] $ 表示將 $ i $ 及其子樹斷開的最小代價,然後發現效率過不去

因為 $ \sum k \leq 5 \times 10^5 $,考慮構造虛樹,然後直接 dp 即可

時間效率:$ o(2\log n\times \sum k) $,因為一棵虛樹最多只有 $ 2k $ 個點,查詢 lca 的效率為 $ o(\log n) $

構造虛樹:

1 #include2

#define ll long long

3#define pb push_back

4#define _(d) while(d(isdigit(ch=getchar())))

5using

namespace

std;

6int

r()9

const

int n=2.5e5+5;10

int n,m,f[n][25

],head[n],cnt,dfn[n],dep[n],a[n],sta[n],top,tot,lg;

11ll g[n];

12 vectorg[n];

13struct edgee[n<<1

];14

bool cmp(int a,int b)

15void add(int s,int t,int w),head[s]=cnt;}

16void dfs(int u,int

far)

23int lca(int x,int

y)29 i=lg;

30while(x!=y)

33return

x;34}35

void insert(int

x)37

int far=lca(x,sta[top]);

38if(far==sta[top])return;39

while(top>1&&dfn[sta[top-1]]>=dfn[far])

40 g[sta[top-1]].pb(sta[top]),top--;

41if(far!=sta[top])g[far].pb(sta[top]),sta[top]=far;

42 sta[++top]=x;

43return;44

}45 ll work(int

x)53

intmain()

68return0;

69 }

view code

bzoj2286 消耗戰 虛樹 樹形dp

解題思路 假如只有一次詢問,可以很好想到樹形dp方程 如果u是關鍵點,則f u w fa u u 如果u不是關鍵點,則f u min w fa u u f son u 但這樣一次複雜度為o n 則總複雜度為o nm 顯然超時。像這種每次詢問都給出多個關鍵點的題,應該建虛樹,即每次詢問都只把關鍵點及其...

BZOJ2286 消耗戰(虛樹,樹形dp)

今天本tu生日,學個新演算法慶祝一下。學了虛樹,碰到每次詢問給你一些點點的樹就不虛了 對於一棵樹,我們可以在上面用我們學過的演算法為所欲為。假設題目有多個詢問,每個詢問給出了一些點,那我們可以把這些點和及有關係的點拉出來,合併點和邊的資訊,構出虛樹,在虛樹上繼續為所欲為。對於與詢問有關係的點,就是這...

BZOJ 2286 消耗戰(虛樹)

因為聽說多校第一場的09可以用虛樹來做,於是趕緊趁著沒比賽補一發相關知識點。臥槽寫完這篇題解之後,突然發現多校09題解給的方法不就是維護一顆動態虛樹嘛!只不過說虛樹是動態的,你需要將點插入虛樹中,就要動態維護這個樹的權值。事實上虛樹就是通過重新建樹,使得樹上的 無用決策點 全部去掉 當然相關資訊必須...