1. 程式人生 > >UVALive - 2038 Strategic game (無向+記憶化+簡單樹形DP)

UVALive - 2038 Strategic game (無向+記憶化+簡單樹形DP)

ace 最小頂點覆蓋 tar 思路 輸出 二分圖 nbsp 二分 mem

題目鏈接: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\n",sum);
	}
} 

  

UVALive - 2038 Strategic game (無向+記憶化+簡單樹形DP)