J. 辞甲猾扎

#include <bits/stdc++.h>
using namespace std;
vector<int>a[1000005];
int id[1000005];
bool c[1000005],b[1000005];
long long f[1000005][3];
/*
对于与黑色点相邻的灰色点: 
0:根节点在之后被父节点染成白色
1:根节点在之后被子节点染成白色
2:根节点初始时染成白色
为了尽量简化问题,尝试把另外两种情况统一到这种DP状态中,为此使用更通用的描述,使用"覆盖"的定义:
0:根节点未能被覆盖 
1:根节点已经被覆盖 
2:根节点染成白色 
*/
void dfs(int n1,int fa)
{
	for(int i=0;i<a[n1].size();i++)
	{
		if(a[n1][i]!=fa)
		{
			dfs(a[n1][i],n1);
		}
	}
	if(b[n1]==false)
	{
		f[n1][2]=1;
		for(int i=0;i<a[n1].size();i++)
		{
			if(a[n1][i]!=fa)
			{
				f[n1][2]+=min(f[a[n1][i]][0],min(f[a[n1][i]][1],f[a[n1][i]][2]));
			}
		}
	}
	else
	{
		f[n1][2]=INT_MAX;
	}
	f[n1][0]=0;
	for(int i=0;i<a[n1].size();i++)
	{
		if(a[n1][i]!=fa)
		{
			f[n1][0]+=min(f[a[n1][i]][1],f[a[n1][i]][2]);
		}
	}
	long long minn=INT_MAX;
	for(int i=0;i<a[n1].size();i++)
	{
		if(a[n1][i]!=fa)
		{
			minn=min(minn,f[a[n1][i]][2]-f[a[n1][i]][1]);
		}
	}
	if(minn<0)
	{
		minn=0;
	}
	f[n1][1]=f[n1][0]+minn;
	if(c[n1]==false)
	{
		f[n1][1]=min(f[n1][0],f[n1][1]);
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=k;i++)
	{
		cin>>id[i];
		b[id[i]]=true;
	}
	for(int i=1;i<n;i++)
	{
		int u,v;
		cin>>u>>v;
		a[u].push_back(v);
		a[v].push_back(u);
	}
	for(int i=1;i<=k;i++)
	{
		for(int j=0;j<a[id[i]].size();j++)
		{
			c[a[id[i]][j]]=true;
		}
	}
	for(int i=1;i<=k;i++)
	{
		c[id[i]]=false;
	}
	dfs(1,0);
	cout<<min(f[1][1],f[1][2])<<endl;
	return 0;
}
posted @ 2025-01-30 15:07  D06  阅读(9)  评论(0)    收藏  举报
//雪花飘落效果