【Tree dp】Perfect service UVA1218

A tree dp stuck for so long. . .

The meaning of the question: In a book, each point can be installed with a server. Asking the minimum number of servers can make each point that is not a server adjacent to exactly one server

Discuss each point

1. Install the server by yourself 2. You are uneasy, the parent node is safe, so that all child nodes cannot be safe 3. You are uneasy, the parent node is uneasy, so that there is only one child node safe

Let dp[i][0] be i and its subtrees, the least server when i is installed. dp[i][2] means that i's father, An's son, is uneasy, dp[i][1] means that one of i's sons, An's father, is uneasy

dp[i][0] can be transferred from 0,1 in the son, dp[i][2] can only be transferred from 1 in the son

The situation with only one son Ann seems a little more troublesome, but it can be seen that all the sons are uneasy, so it is equal to dp[i][2], and then select a son to become Ann, which will produce a difference, and finally Add the smallest difference among all sons


Then I got angry and found WA? ? Then the xjb changes are useless, and then I stared at the code for a long time and my brain opened and found that my INF opened 20 million according to the custom, so the situation of the leaf node son An is INF, but if there is a node connected to many leaf nodes, It is very likely that INT will explode when transferring. Code is weak. . .


#include<iostream>
#include<cstdio>
#include<cstring>
#define MAXN (20010)
#define INF (210010)
using namespace std;
int n,m1,h[MAXN],dp[MAXN][3];
struct edge{
	int next,to;
	void Add(int Next,int To){
		next=Next; to=To;
	}
}q[MAXN];
void addedge(int x,int y){
	q[++m1].Add(h[x],y); h[x]=m1;
	q[++m1].Add(h[y],x); h[y]=m1;
}
void Dfs(int x,int fa){
	int i, y, k = INF;
	dp[x][0]=1; dp[x][1]=dp[x][2]=0;
	for (i=h[x];i;i=q[i].next){
		y=q[i].to;
		if (y==fa) continue;
		Dfs(y,x);
		dp[x][0]+=min(dp[y][0],dp[y][2]);
		dp[x][2]+=dp[y][1];
		k=min(k,dp[y][0]-dp[y][1]);
	}
	dp[x][1]=dp[x][2]+k;
}
int main(){
	while (cin>>n){
		memset(h,0,sizeof(h));
		memset(q,0,sizeof(q));
		memset(dp,0,sizeof(dp));
		m1=0;
		int x,y;
		for (int i=1;i<=n-1;i++){
			scanf("%d %d",&x,&y);
			addedge(x,y);
		}
		scanf("%d",&x);
		Dfs(1,0);
		printf("%d\n",min(dp[1][0],dp[1][1]));
		if (x==-1) break;
	}
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325935840&siteId=291194637