#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#include<queue>
using namespace std;
const int maxn=100000;
int n;
vector<int> sons[maxn];
int a,b,c;
int d[maxn][3];
int vis[maxn];
int dp(int u)
{
vis[u]=1;
d[u][0]=1;d[u][1]=0;d[u][2]=maxn;//最后一层的u是否设立maxn会影响?
queue<int>q;//这个题里只是说到的是树状的,因为父亲结点的影响 不像一般的树那么好处理,所以一般是用到了队列来进行操作。
for(int i=0;i<sons[u].size();i++)
{
if(!vis[sons[u][i]])//除去父亲结点的影响
{
dp(sons[u][i]);
q.push(sons[u][i]);
d[u][0]+=min(d[sons[u][i]][0],d[sons[u][i]][1]);
d[u][1]+=d[sons[u][i]][2];
}
}
while(!q.empty())//之所以用到queue是因为要把d[u][1]先全部计算好再用到下面的公式,这样就因为父亲结点的影响不能再跑循环,利用queue就可以很好的解决了
{
d[u][2]=min(d[u][2],d[u][1]-d[q.front()][2]+d[q.front()][0]);
q.pop();
}
return 0;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(d,0,sizeof(d));
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
sons[i].clear();
for(int i=1;i<n;i++)
{
scanf("%d%d",&a,&b);
sons[a].push_back(b);
sons[b].push_back(a);
}
dp(1);
printf("%d\n",min(d[1][0],d[1][2]));
scanf("%d",&c);
if(c==-1)
break;
}
return 0;
}
UVa 1218
最新推荐文章于 2022-10-18 16:35:38 发布