题目链接:https://vjudge.net/problem/UVALive-2038
题意:给定一棵树,选择尽量少的点,
使得每个没有选中的结点至少和一个已经选中的结点相邻。
输出最少需要选择的节点数。
思路:经典的二分图最小顶点覆盖, 也是经典的树形 DP
AC代码:
#include<stdio.h> #include<string.h> #include<vector> #include<algorithm> using namespace std; const int MAXN=1500+10; int d[MAXN][2],n; vector<int>G[MAXN]; int f(int u,int fa,int mark) { if(d[u][mark]!=-1) return d[u][mark]; //记忆化 int &ans=d[u][mark]; ans=mark; for(int i=0;i<G[u].size();i++) { int v=G[u][i]; if(v==fa) continue; if(mark) ans+=min(f(v,u,0),f(v,u,1)); //选 else ans+=f(v,u,1);//不选 } return ans; } int main() { while(~scanf("%d",&n)) { int u,v,t; for(int i=0;i<=MAXN;i++) G[i].clear(); for(int i=0;i<n;i++) { scanf("%d:(%d)",&u,&t); for(int j=0;j<t;j++) { scanf("%d",&v); G[u].push_back(v); G[v].push_back(u); } } memset(d,-1,sizeof(d)); int sum=min(f(0,-1,0),f(0,-1,1)); printf("%d ",sum); } }