給你一棵樹和樹上的許多條從後代到祖先的鏈,選擇每條鏈需要一定代價,問覆蓋整棵樹的所有點的最小代價是多少。
\(n,m\leq 100000\)
(由於時間過於久遠,所以直接說正解算了)
對於這樣的題,顯然有一種暴力的dp做法。
設\(f_\)表示\(i\)子樹全部被覆蓋,其中伸出來的一條鏈到達深度為\(j\)的祖先時的最小代價。
轉移不在此贅述。
然後可以線段樹優化。
有兩種情況:從\(i\)子樹伸出來的鏈是最高的;從\(i\)伸出來的鏈是最高的。
我們欽定某一條鏈是最高的,不用管是否存在其他的鏈高過它的情況,因為如果有那樣的情況,那麼這個狀態的答案就會被覆蓋掉。
首先記錄一下每個子樹的最優答案之和,記作\(sum\)。
枚舉子樹,對於它的所有狀態加上\(sum\),減去它本身的最優答案。也就是將其它子樹的答案之和給它加上。對於自己,就直接用\(sum\)加上所選擇的鏈的代價。
然後線段樹合併即可。
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)
a->pushdown(),b->pushdown();
int mid=l+r>>1;
a->l=merge(a->l,b->l,l,mid,plus,en);
if (midr=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()
for (int i=1;imn);
return 0;
}
這種樹上dp的東西很多時候都可以揹包啊……
JZOJ6258 省選模擬8 9 轟炸
給你一棵樹和樹上的許多條從後代到祖先的鏈,選擇每條鏈需要一定代價,問覆蓋整棵樹的所有點的最小代價是多少。n m 100000 n,m leq 100000 n,m 10 0000 由於時間過於久遠,所以直接說正解算了 對於這樣的題,顯然有一種暴力的dp做法。設f i,jf fi,j 表示i ii子樹...
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 這樣...