給你一棵樹和樹上的許多條從後代到祖先的鏈,選擇每條鏈需要一定代價,問覆蓋整棵樹的所有點的最小代價是多少。
n ,m
≤100000
n,m\leq 100000
n,m≤10
0000
(由於時間過於久遠,所以直接說正解算了)
對於這樣的題,顯然有一種暴力的dp做法。
設f i,
jf_
fi,j
表示i
ii子樹全部被覆蓋,其中伸出來的一條鏈到達深度為j
jj的祖先時的最小代價。
轉移不在此贅述。
然後可以線段樹優化。
有兩種情況:從i
ii子樹伸出來的鏈是最高的;從i
ii伸出來的鏈是最高的。
我們欽定某一條鏈是最高的,不用管是否存在其他的鏈高過它的情況,因為如果有那樣的情況,那麼這個狀態的答案就會被覆蓋掉。
首先記錄一下每個子樹的最優答案之和,記作sum
sumsu
m。枚舉子樹,對於它的所有狀態加上sum
sumsu
m,減去它本身的最優答案。也就是將其它子樹的答案之和給它加上。對於自己,就直接用sum
sumsu
m加上所選擇的鏈的代價。
然後線段樹合併即可。
using
namespace std;
#include
#include
#include
#include
#define n 300010
#define inf 1000000000000000000
int n,m;
struct edge e[n*2]
;int ne;
edge *last[n]
;int dep[n]
;struct edge2 e2[n*2]
;int ne2;
edge2 *last2[n]
;struct node
inline
void
update()
} d[n*30]
,*null;
int cnt;
inline node *
newnode()
);}node *root[n]
;void
change
(node *t,
int l,
int r,
int x,
long
long c)
t->
pushdown()
;int mid=l+r>>1;
if(x<=mid)
change
(t->l==null?t-
>l=
newnode()
:t->l,l,mid,x,c)
;else
change
(t->r==null?t-
>r=
newnode()
:t->r,mid+
1,r,x,c)
; t-
>
update()
;}void
cut(node *t,
int l,
int r,
int en)
else
cut(t-
>r,mid+
1,r,en)
; t-
>
update()
;}node *
merge
(node *a,node *b,
int l,
int r,
long
long plus,
int en)
if(b==null)
return a;
if(l==r)
a->
pushdown()
,b->
pushdown()
;int mid=l+r>>1;
a->l=
merge
(a->l,b-
>l,l,mid,plus,en);if
(mida-
>r=
merge
(a->r,b-
>r,mid+
1,r,plus,en)
;else
a->r=null;
a->
update()
;return a;
}bool
dfs(
int x,
int fa)
node *un=
newnode()
;for
(edge *ei=last[x]
;ei;ei=ei-
>las)
if(ei-
>to!=fa)
un=merge
(un,root[ei-
>to],1
,n,sum-root[ei-
>to]
->mn,x==1?
1:dep[x]-1
);for(edge2 *ei=last2[x]
;ei;ei=ei-
>las)
change
(un,
1,n,dep[ei-
>to]
,ei-
>w+sum)
; root[x]
=un;
return root[x]
->mn>=inf;
}int
main()
; last[u]
=e+ne++
; e[ne]=;
last[v]
=e+ne++;}
for(
int i=
1;i<=m;
++i)
; last2[u]
=e2+ne2++;}
null=d;
*null=;if
(dfs(1
,0))
printf
("-1\n");
else
printf
("%lld\n"
,root[1]
->mn)
;return0;
}
這種樹上dp的東西很多時候都可以揹包啊……
JZOJ6258 省選模擬8 9 轟炸
給你一棵樹和樹上的許多條從後代到祖先的鏈,選擇每條鏈需要一定代價,問覆蓋整棵樹的所有點的最小代價是多少。n,m leq 100000 由於時間過於久遠,所以直接說正解算了 對於這樣的題,顯然有一種暴力的dp做法。設 f 表示 i 子樹全部被覆蓋,其中伸出來的一條鏈到達深度為 j 的祖先時的最小代價。...
JZOJ6257 省選模擬8 9 修路
有一堆點,每個點都有其權值c ic i ci 每次插入邊 u,v u,v u,v u uu和1 11連通,v vv和1 11不連通。最後保證形成一棵樹。每次插入的時候詢問1 11到u uu的路徑上逆序對的個數。然後將1 11到u uu的路徑上的所有節點的權值設為c vc v cv 一看就知道是什麼資...
JZOJ 省選模擬 string
一行乙個整數表示答案。sample input 樣例輸入 3 3sample output 樣例輸出 首先我們忽略重複的字串,定義 n 表示長度為 n 的回文串,或由兩個回文串拼成的字串數量。那麼可以通過列舉第乙個回文串的長度 可以為 0 可以算出f n 但是正如剛才所說,會對如 abaaba 這樣...