POJ1463

树上的最小点覆盖,如果不是树则是NP复杂问题。

对于树上的某个点,如果不被选中,则它相邻的节点必然被选中,如果选中它,则取相邻节点选中或不选中的较小值。

代码很简单。

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<vector>
using namespace std;
const int maxn=1500;
vector<int> adj[maxn];
int dp[maxn][2];
int dfs(int cur,int flag,int fa)
{
 if(dp[cur][flag]!=-1)return dp[cur][flag];
 if((adj[cur].size()==0&&fa==-1)||(adj[cur].size()==1&&adj[cur][0]==fa))
 	return flag;
 int ans=flag;
 for(int i=0;i<adj[cur].size();i++)
 	{
 	 int ne=adj[cur][i];
	 if(ne==fa)continue;
	 if(flag==0)ans+=dfs(ne,1-flag,cur);	
	 	else ans+=min(dfs(ne,flag,cur),dfs(ne,1-flag,cur));
	}
 return dp[cur][flag]=ans;
}
int main()
{freopen("t.txt","r",stdin);
 int n;
 while(scanf("%d",&n)!=EOF)
 	{for(int i=0;i<n;i++)dp[i][0]=dp[i][1]=-1;
 	 for(int i=0;i<n;i++)adj[i].clear();
	 for(int i=0;i<n;i++)
	 	{
	 	 int np;scanf("%d",&np);getchar();getchar();
		 int m,ne;scanf("%d",&m);getchar();
		 for(int j=0;j<m;j++)
		 	{
		 		scanf("%d",&ne);
		 		adj[np].push_back(ne);
		 		adj[ne].push_back(np);
			}	
		}
	 printf("%d\n",min(dfs(0,0,-1),dfs(0,1,-1)));	
	}
 return 0;
}

  

posted on 2017-05-16 19:45  Bingsen  阅读(148)  评论(0编辑  收藏  举报