BZOJ3611 大工程(虛樹,動態規劃)

2022-03-20 05:54:15 字數 1638 閱讀 8844

bzoj

國家有乙個大工程,要給乙個非常大的交通網路裡建一些新的通道。

我們這個國家位置非常特殊,可以看成是乙個單位邊權的樹,城市位於頂點上。

在 2 個國家 a,b 之間建一條新通道需要的代價為樹上 a,b 的最短路徑。

現在國家有很多個計畫,每個計畫都是這樣,我們選中了 k 個點,然後在它們兩兩之間 新建 c(k,2)條 新通道。

現在對於每個計畫,我們想知道:

1.這些新通道的代價和

2.這些新通道中代價最小的是多少

3.這些新通道中代價最大的是多少

第一行 n 表示點數。

接下來 n-1 行,每行兩個數 a,b 表示 a 和 b 之間有一條邊。

點從 1 開始標號。 接下來一行 q 表示計畫數。

對每個計畫有 2 行,第一行 k 表示這個計畫選中了幾個點。

第二行用空格隔開的 k 個互不相同的數表示選了哪 k 個點。

輸出 q 行,每行三個數分別表示代價和,最小代價,最大代價。

2 13 2

4 15 2

6 47 5

8 69 7

10 9

5 410 4

5 26 1

6 13 3 3

6 6 6

1 1 1

2 2 2

2 2 2

n<=1000000

q<=50000並且保證所有k之和<=2*n

先考慮正常的\(dp\)

對於第乙個,總和。設\(f[i]\)表示\(i\)的子樹中的關鍵點的個數

轉移:\(sum+=f[v]*(k-f[v])*len(i,v),f[i]+=f[v]\)

對於第二個和第三個,相當於維護樹上最長鏈和最短鏈

這個就非常基礎了,不寫了。

現在再把這個\(dp\)放在虛樹上做就行了

#include#include#include#include#include#include#include#include#include#includeusing namespace std;

#define ll long long

#define rg register

#define max 1001000

inline int read()

struct linee[max<<1];

int h[max],cnt=1;

inline void add(int u,int v,int w);h[u]=cnt++;}

int n,q,k;

int fa[max],size[max],hson[max],dep[max],top[max],dfn[max],low[max],tim;

void dfs1(int u,int ff)

}void dfs2(int u,int tp)

low[u]=tim;

}int lca(int u,int v)

sum=0;min=1e9;max=-1e9;dp(p[1]);

printf("%lld %d %d\n",sum,min,max);

for(int i=1;i<=k;++i)vis[p[i]]=false,h[p[i]]=0;

} return 0;

}

BZOJ3611 大工程(虛樹,動態規劃)

bzoj 國家有乙個大工程,要給乙個非常大的交通網路裡建一些新的通道。我們這個國家位置非常特殊,可以看成是乙個單位邊權的樹,城市位於頂點上。在 2 個國家 a,b 之間建一條新通道需要的代價為樹上 a,b 的最短路徑。現在國家有很多個計畫,每個計畫都是這樣,我們選中了 k 個點,然後在它們兩兩之間 ...

bzoj3611 大工程 虛樹 dp

國家有乙個大工程,要給乙個非常大的交通網路裡建一些新的通道。我們這個國家位置非常特殊,可以看成是乙個單位邊權的樹,城市位於頂點上。在 2 個國家 a,b 之間建一條新通道需要的代價為樹上 a,b 的最短路徑。現在國家有很多個計畫,每個計畫都是這樣,我們選中了 k 個點,然後在它們兩兩之間 新建 c ...

Luogu P4103大工程(虛樹DP)

題目鏈結 我貌似發現這類dp就是先別管什麼虛樹 把樹形dp搞出來套上虛樹板子就好了 這個樹形dp就是設sum為答案,sumd為子樹內所有點的深度和 當然指的是被詢問的點 maxi指子樹內最深的點的深度,mini同理 然後考慮我們dfs到x,它的兒子已經遍歷到一半,新加進來乙個兒子to 顯然 sum ...