description如果樹的點數少,可以用\(dp[u]\)表示子樹的所有關鍵點都不連通的最小代價,如果子節點\(v\)是關鍵點,則一定斷開\(uv\)這條邊,否則選擇是斷開\(uv\),還是使用子樹內的邊來阻斷,轉移即可,\(o(nq)\)。在一場戰爭中,戰場由n個島嶼和n-1個橋梁組成,保證每兩個島嶼間有且僅有一條路徑可達。現在,我軍已經偵查到敵軍的總部在編號為1的島嶼,而且他們已經沒有足夠多的能源維繫戰鬥,我軍勝利在望。已知在其他k個島嶼上有豐富能源,為了防止敵軍獲取能源,我軍的任務是炸毀一些橋梁,使得敵軍不能到達任何能源豐富的島嶼。由於不同橋梁的材質和結構不同,所以炸毀不同的橋梁有不同的代價,我軍希望在滿足目標的同時使得總代價最小。
偵查部門還發現,敵軍有一台神秘機器。即使我軍切斷所有能源之後,他們也可以用那台機器。機器產生的效果不僅僅會修復所有我軍炸毀的橋梁,而且會重新隨機資源分布(但可以保證的是,資源不會分布到1號島嶼上)。不過偵查部門還發現了這台機器只能夠使用m次,所以我們只需要把每次任務完成即可。
input
第一行乙個整數n,代表島嶼數量。
接下來n-1行,每行三個整數u,v,w,代表u號島嶼和v號島嶼由一條代價為c的橋梁直接相連,保證1<=u,v<=n且1<=c<=100000。
第n+1行,乙個整數m,代表敵方機器能使用的次數。
接下來m行,每行乙個整數ki,代表第i次後,有ki個島嶼資源豐富,接下來k個整數h1,h2,…hk,表示資源豐富島嶼的編號。
output
輸出有m行,分別代表每次任務的最小代價。
不難發現其中很多點是無用的,對我們有用的點其實只有所有的關鍵點和他們之間的\(lca\),虛樹就是在不改變祖先與後代關係的情況下,保留了一些有用點,把一整顆樹的資訊進行壓縮,建出一棵小樹。
我們可以通過將關鍵點按\(dfs\)序排序,求出一些相鄰點的\(lca\),將他們加入虛樹中,同時保持祖先與後代的關係,這裡可以看出詢問\(n\)個關鍵點時,虛樹的節點數n小於等於\(2n-1\)
使用單調棧建虛樹,為了方便我們把\(1\)加入虛樹中。用單調棧來維護一條虛樹上的鏈,也就是乙個棧裡相鄰的兩個節點在虛樹上也是相鄰的,而且棧是從底部到棧首單調\(dfs\)序遞增的。
太懶了。。演算法細節還是看這裡
對於本題,建出虛樹後我們還要維護一些被壓縮路徑的最小值,可以倍增維護
#include typedef long long ll;
const int n = 250010;
using namespace std;
int n, q;
struct edge e[n << 1];
int cc, h[n];
void add(int u,int v,int w)
int dfn[n], id, fa[n][20], dep[n], mn[n][20];
void dfs(int u, int pre)
for(int i = h[u]; ~i; i = e[i].nxt)
}int lca(int u, int v)
int calmn(int u, int v)
bool cmp(int u, int v)
int a[n], mk[n], stc[n], top;
void build(int a, int m)
if(dfn[p] > dfn[stc[top-1]])
else
}h[a[i]] = -1, stc[++top] = a[i];}}
for(int w, i = 1; i < top; ++i)
}ll dp[n];
void dp(int u)
}int main()
dfs(1,0);
scanf("%d",&q);
while(q--)
}
日常學習 Virtual Tree 虛樹)
虛樹,顧名思義就是虛構的樹,它是一種用來解決樹上問題的演算法,主要思想是只將原樹上必要的點和它們的最近公共祖先取出來,構成一棵虛樹,並保留他們在樹上的相對關係。我們先來看一道題 給定一棵n個點的樹,每次詢問給定乙個大小為k的點集,你需要切掉一些邊,使得點集中的點均不與1號點聯通,而每條邊都有被切掉所...
Virtual Tree 學習筆記
像大部分虛樹介紹一樣,以一道 爛大街 的例題 sdoi2011 消耗戰 引入 給定一棵大小為 n 的樹,每條邊有邊權,m 組詢問,每次詢問給定 k 個關鍵點,要求切斷 1 與所有關鍵點的路徑,求最小代價。2 leq n leq 2.5 times 10 5 m geq 1 sum leq 5 tim...
虛樹學習小結
其實虛樹這東西 不知道說什麼好 簡單易學呃 虛樹主要處理一種詢問總點數不超過o n 且每次詢問的那些點,在預處理之後,所求的值,只和他們,以及他們兩兩的lca有關 這裡有個顯然的結論,即m個點兩兩的lca不超過m 1個,將這m個點按dfs序排序之後相鄰兩點的m 1個lca就是這m個點兩兩的lca 建...