皇宫看守(树形dp)

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int n,head[2005],dp[2005][3],fa[2005],w[2005],cnt;

struct edge{
	int v,next;
}e[2005];

inline void add(int u,int v){
	e[++cnt].v=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}

inline int root(int v){
	if(fa[v]==-1)return v;
	return root(fa[v]);
}

//0:自无,父有 1:自有 2:自无父无,子有的有 
inline void guess(int u){
	int minn=2147483647,k=0;
	for(int i=head[u];i!=-1;i=e[i].next){
		int v=e[i].v;
		guess(v);
		dp[u][1]+=min(dp[v][0],dp[v][1]);
		dp[u][0]+=min(dp[v][1],dp[v][2]);
		if(dp[v][1]<dp[v][2]){
			dp[u][2]+=dp[v][1];
			k++;
		}
		else{
			dp[u][2]+=dp[v][2];
			minn=min(minn,dp[v][1]-dp[v][2]);
		}
	}
	dp[u][1]+=w[u];
	if(k==0)dp[u][2]+=minn;
}

int main(){
	memset(head,-1,sizeof(head));
	memset(fa,-1,sizeof(fa));
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		int u,k,m;
		scanf("%d%d%d",&u,&k,&m);
		w[u]=k;
		while(m--){
			int x;
			scanf("%d",&x);
			add(u,x);
			fa[x]=u;
		}
	}
	int rt=root(1);
	guess(rt);
	printf("%d\n",min(dp[rt][1],dp[rt][2]));
}
posted @ 2019-07-30 11:36  Y15BeTa  阅读(190)  评论(0编辑  收藏  举报