題意: 對於一棵有n個結點的無根樹,選出盡量多的結點,使得任何兩個結點均不相鄰(稱為最大獨立集)。
sol:樹形dp
由於每個點只由其兒子或者孫子決定(二者的最大值),所以我們可以深搜一遍,回溯的時候用當前節點更新其父親以及父親的父親(因為此時該節點的值已經被我們計算出來了),這種由已知貢獻給未知的方法稱為刷表法。
刷表法的唯一限制是,對於乙個狀態(記為s)所依賴的所有狀態(記為s')而言,這些狀態對當前狀態的貢獻必須是獨立的。(即s'是互相獨立的)
如此可以寫出dp。
#include #include#include
using
namespace
std;
const
int maxn = 105, maxm = maxn * 2
;int
n, tot;
int fa[maxn][25
], s[maxn], gs[maxn], h[maxn], d[maxn];
struct
edge
a[maxm];
void add(int x, int
y)void dfs(int u, int
fat)
d[u] = max(s[u], gs[u] + 1
);//此時d[u]的值已經被計算出來了。
s[fa[u][
0]] +=d[u];//貢獻給父親
gs[fa[u][
1]] +=d[u];//貢獻給父親的父親
}int
main()
dfs(
1, 0
); printf("%d
", d[1
]);
return0;
}
另外,uva1220還要求給出當前最優解是否唯一,這個貌似也要用dp做,之後補坑。
樹的最大獨立集
include include includeusing namespace std ifstream fin c data19.in struct node int data int c int gc struct node parent struct node left struct node ...
uva1220樹的最大獨立集
題意 公司裡除了老闆,每個人都有乙個直屬上司,要求選盡量多的人,但不能同時選乙個人和他的直屬上司,問最多能選多少個人,以及在人數最多的情況下方案是否唯一。思路 d u 0 表示不選u點能得到的最大人數d u 0 sum d u 1 表示選u點能得到的最大人數d u 1 sum f u 0 表示不選u...
uva1220 樹的最大獨立集 判重
題意是挑選盡量多的人,並且每個人都不和他的父節點同時出現,很明顯的最大獨立集問題,難點在於如何判斷方案是否唯一。詳情請見劉汝佳 演算法競賽入門經典 第二版 p282 include include include include include include include define inf ...