从底向上,能合并就合并,标记一下经过根节点的路径是哪种路径(就两种很好yy)。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,cnt,T;
int head[10005],list[20005],next[20005];
int f[10005],v[10005];
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
inline void insert(int x,int y)
{
next[++cnt]=head[x];
head[x]=cnt;
list[cnt]=y;
}
void dfs(int x,int fa)
{
int tmp=0;
f[x]=1;
for (int i=head[x];i;i=next[i])
if (list[i]!=fa)
{
dfs(list[i],x);
f[x]+=f[list[i]];
if (!v[list[i]]) tmp++;
}
if (tmp>=2) f[x]-=2,v[x]=1;
else if (tmp==1) f[x]--;
}
int main()
{
T=read();
while (T--)
{
n=read(); cnt=0;
memset(head,0,sizeof(head));
memset(f,0,sizeof(f));
memset(v,0,sizeof(v));
for (int i=1;i<n;i++)
{
int u=read(),v=read();
insert(u,v); insert(v,u);
}
dfs(1,0);
printf("%d\n",f[1]);
}
return 0;
}