【名词解释】
每个测试文件均包含多组测试数据。第一行输入一个整数
代表数据组数,每组测试数据描述如下:
第一行输入一个整数
。
之后的
行,每行输入两个整数
,代表有一条边连接
。
除此之外,保证单个测试文件的
之和不超过
。
对于每组测试数据,新起一行。
在一行内输出
个整数,依次代表
号节点的子树的权值。
1 5 1 2 2 3 3 4 3 5
2 1 1 0 0
以
号点为根的子树:删除
号节点后符合要求,权值为
;
以
号点为根的子树:删除
号节点后符合要求,权值为
;
以
号点为根的子树:删除
号节点后符合要求,权值为
;
以
号点为根的子树:初始状态已经符合要求,权值为
;
以
号点为根的子树:初始状态已经符合要求,权值为
。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 998244353;
int dp[100001][2];
struct Edge{
int to,next;
};
int indx=0;
int head[100001];
void add(Edge edge[],int u,int v){
edge[indx].to=v;
edge[indx].next=head[u];
head[u]=indx++;
}
void dfs(int u,int parent,Edge edge[]){
dp[u][1]=1;
dp[u][0]=0;
for(int i=head[u];i!=-1;i=edge[i].next){
if(edge[i].to!=parent)
{
dfs(edge[i].to,u,edge);
dp[u][1]+=min(dp[edge[i].to][0],dp[edge[i].to][1]);
dp[u][0]+=dp[edge[i].to][1];
}
}
}
int main(){
int t;
cin>>t;
while(t--){
indx=0;
memset(dp,0x3f,sizeof(dp));
memset(head,-1,sizeof(head));
int n;
cin>>n;
Edge edge[2*n+1];
for(int i=1;i<=n-1;i++){
int u,v;
cin>>u>>v;
add(edge,u,v);
add(edge,v,u);
}
dfs(1,-1,edge);
for(int i=1;i<=n;i++){
cout<<min(dp[i][1],dp[i][0])<<" ";
}
cout<<endl;
}
}