[APIO2012 巡逻]

[关键字]:动态规划

[题目大意]:说也说不清楚

//=====================================================================

[分析]:k=1很好做就是求出最长链就行了,因为假如这条链后必定会产生环,而环上的点必定只需走一次,所以答案就是2*(n-1)-s,s就是最长链的长度。k=2时也可以求最长链,由k=1时可以看出最长链的长度就是2*(n-1)需要减掉多少,于是把第一条链所经过的边变成-1再找一遍。第二种方法是动态规划,可以求出一棵树中k条不相交的链最长总合,而这道题中任意两条相交的链(a,b)\(c,d)都可以变成(a,c)(b,d)从而不相交。

设立状态f[i,j,k]表示点i的子树中,找j条链,并且链的状态是k

K有两种:APIO <wbr>2010 <wbr>巡逻

 

K=0为一条经过点i的长链。

K=1为到点i的半条链。

那么

f[I,j,0]=max(f[I,j,0],f[y,k,0]+f[I,j-k,0]) 表示累加儿子一条长链的答案

f[I,j,0]= max(f[I,j,0],f[y,k,1]+f[I,j-k-1,1]+1) 表示儿子节点的一条半条链+iy的一条链组成一个新的半条链。

f[I,j,1]= max(f[I,j,1],f[y,k,0]+f[I,j-k,1])表示不放弃自己的半条链然后累加儿子的长链

f[I,j,1]= max(f[I,j,1],f[y,k,1]+f[I,j-k,0])+1表示自己的一条半条链然后累加儿子的一条长链 

最后输出2*( n-1 ) –max(f[1,k,0] , f[1,k-1,1] ,f[1,1,0] )+k

APIO <wbr>2010 <wbr>巡逻

最后还要注意这种情况,k=2,一条最长链就够了

[代码]:

你可能感兴趣的:(2012)