【NOI2002】贪吃的九头龙
Description
傳說(shuō)中的九頭龍是一種特別貪吃的動(dòng)物。雖然名字叫“九頭龍”,但這只是說(shuō)它出生的時(shí)候有九個(gè)頭,而在成長(zhǎng)的過(guò)程中,它有時(shí)會(huì)長(zhǎng)出很多的新頭,頭的總數(shù)會(huì)遠(yuǎn)大于九,當(dāng)然也會(huì)有舊頭因衰老而自己脫落。
有一天,有M個(gè)腦袋的九頭龍看到一棵長(zhǎng)有N個(gè)果子的果樹(shù),喜出望外,恨不得一口把它全部吃掉。可是必須照顧到每個(gè)頭,因此它需要把N個(gè)果子分成M組,每組至少有一個(gè)果子,讓每個(gè)頭吃一組。
這M個(gè)腦袋中有一個(gè)最大,稱為“大頭”,是眾頭之首,它要吃掉恰好K個(gè)果子,而且K個(gè)果子中理所當(dāng)然地應(yīng)該包括唯一的一個(gè)最大的果子。果子由N-1根樹(shù)枝連接起來(lái),由于果樹(shù)是一個(gè)整體,因此可以從任意一個(gè)果子出發(fā)沿著樹(shù)枝“走到”任何一個(gè)其他的果子。
對(duì)于每段樹(shù)枝,如果它所連接的兩個(gè)果子需要由不同的頭來(lái)吃掉,那么兩個(gè)頭會(huì)共同把樹(shù)枝弄斷而把果子分開(kāi);如果這兩個(gè)果子是由同一個(gè)頭來(lái)吃掉,那么這個(gè)頭會(huì)懶得把它弄斷而直接把果子連同樹(shù)枝一起吃掉。當(dāng)然,吃樹(shù)枝并不是很舒服的,因此每段樹(shù)枝都有一個(gè)吃下去的“難受值”,而九頭龍的難受值就是所有頭吃掉的樹(shù)枝的“難受值”之和。
九頭龍希望它的“難受值”盡量小,你能幫它算算嗎?
例如圖1所示的例子中,果樹(shù)包含8個(gè)果子,7段樹(shù)枝,各段樹(shù)枝的“難受值”標(biāo)記在了樹(shù)枝的旁邊。九頭龍有兩個(gè)腦袋,大頭需要吃掉4個(gè)果子,其中必須包含最大的果子。即N=8,M=2,K=4:
Input
輸入文件的第1行包含三個(gè)整數(shù)N (1<=N<=300),M (2<=M<=N),K (1<=K<=N)。 N個(gè)果子依次編號(hào)1,2,…,N,且最大的果子的編號(hào)總是1。第2行到第N行描述了果樹(shù)的形態(tài),每行包含三個(gè)整數(shù)a (1<=a<=N),b (1<=b<=N),c (0<=c<=10^5),表示存在一段難受值為c的樹(shù)枝連接果子a和果子b。
Output
輸出文件僅有一行,包含一個(gè)整數(shù),表示在滿足“大頭”的要求的前提下,九頭龍的難受值的最小值。如果無(wú)法滿足要求,輸出-1。
Sample Input
8 2 4
1 2 20
1 3 4
1 4 13
2 5 10
2 6 12
3 7 15
3 8 5
Sample Output
4
.
.
.
.
.
分析
看了z大佬的博客才懂了這題
把題目簡(jiǎn)化一下:
將一棵樹(shù)的結(jié)點(diǎn)染成m種顏色,每個(gè)結(jié)點(diǎn)只有一種顏色,在一條邊兩邊的結(jié)點(diǎn)的顏色相同會(huì)產(chǎn)生費(fèi)用
(1)第1個(gè)結(jié)點(diǎn)必須是1顏色
(2)必須有k個(gè)1顏色
(3)每種顏色必須有一個(gè)結(jié)點(diǎn)
那么,可以發(fā)現(xiàn)一個(gè)性質(zhì):
如果m>2,那么對(duì)答案有貢獻(xiàn)的就只有和1相連的邊,其他的邊不會(huì)產(chǎn)生其他的價(jià)值
如果m=2,那么只有1,2兩種顏色
如果n-k< m-1,那么表示果子不夠吃,輸出-1
設(shè)f[i][j][0/1]為以i為根的子樹(shù)中,有j個(gè)1顏色,根染顏色1或不染顏色1的價(jià)值
與同顏色相連的,要加上邊的價(jià)值;否則,就不加。
.
.
.
.
.
程序:
#include<iostream> #include<string.h> using namespace std; int n,m,k,s[301],f[301][301][2],head[301],cnt; struct edge {int to,from,v; }e[601];void insert(int x,int y,int z) {e[++cnt].to=y;e[cnt].from=head[x];e[cnt].v=z;head[x]=cnt; } void dp(int x,int fa) {int k[301][2],p=0;s[x]=1; f[x][1][1]=f[x][0][0]=0;for (int i=head[x];i;i=e[i].from){int son=e[i].to;if (son==fa) continue;dp(son,x);s[x]+=s[son];memcpy(k,f[x],sizeof(k));memset(f[x],60,sizeof(f[x]));if (m==2) p=e[i].v;for (int j=s[x];j>=0;j--){if (j>0) for (int w=j-1;w>=0;w--) f[x][j][1]=min(f[x][j][1],k[j-w][1]+min(f[son][w][1]+e[i].v,f[son][w][0]));for (int w=j;w>=0;w--) f[x][j][0]=min(f[x][j][0],k[j-w][0]+min(f[son][w][0]+p,f[son][w][1]));}} }int main() {int x,y,z;cin>>n>>m>>k;if (n-k<m-1) {cout<<-1;return 0; }for (int i=1;i<=n-1;i++){cin>>x>>y>>z;insert(x,y,z);insert(y,x,z);}memset(f,60,sizeof(f));dp(1,0);cout<<f[1][k][1];return 0; }轉(zhuǎn)載于:https://www.cnblogs.com/YYC-0304/p/9499937.html
總結(jié)
以上是生活随笔為你收集整理的【NOI2002】贪吃的九头龙的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【CQOI2009】叶子的颜色
- 下一篇: 删边