题意:给定一棵树,选一个点集,使得所有边都与点集中的点相关联,求最小的点集。即最小点覆盖。
思路:一开始自己想到贪心,写出来也AC了,然后认识了树形dp。1、贪心:考虑叶子节点,如果选叶子节点,那么变换成不选叶子节点而选其父节点至少就能够覆盖这条边,而且还能覆盖更多的边。所以叶子节点是必然不选的,而其临接点是必然要选的。如此这般,用一个数组记录各点的度,用一个队列记录叶子节点,然后贪心选点。2、树形dp。一个点i选或不选只有两种可能,分别用dp[i][0]和dp[i][1]表示。dp[i][0]的话,其所有儿子必须选;dp[i][1]的话,其所有儿子可选可不选。用这个思路做dp即可。
1、贪心:
#include <stdio.h>
#include <string.h>
#define N 1505
struct edge{
int x,y,next;
}e[N<<1];
int n,d[N],first[N],q[N],top;
void add(int x,int y){
e[top].y = y;
e[top].next = first[x];
first[x] = top++;
}
int main(){
freopen("a.txt","r",stdin);
while(scanf("%d",&n)!=EOF){
int i,j,k,res=0,num,now,front,rear;
top = 0;
rear = front = -1;
memset(first,-1,sizeof(first));
memset(d,0,sizeof(d));