To_Heart—题解——叶子清除计划
题目描述
⼩Y同学是⼀位数据结构⼤师同时也是⼀位园艺⼤师。
秋天到了,⼩Y同学需要对学校内的⼀棵树展现他顶尖的修叶⽔平。
学校内的这棵树是⼀颗拥有 n n n个点的⽆根树,每次⼩Y会删去所有的叶⼦节点(即度数小于等于1的节点),直到所有的点都被删除了为⽌。
⼩Y现在想问你对于每个点,求出它是第⼏次操作中被删除的。
输入格式
第⼀⾏⼀个数字 n n n,表⽰树上节点个数
接下来 n − 1 n−1 n−1⾏,每⾏两个数字 u u u, v v v,表⽰树上的⼀条边。
输出格式
⼀⾏ n n n个数字,第 i i i个数字表⽰节点 i i i在第⼏次操作中被删除。
样例输入1:
5
1 2
1 3
2 4
2 5
样例输出1:
2 2 1 1 1
样例输入2:
4
1 2
1 3
1 4
样例输出2:
2 1 1 1
数据范围与提示
对于 30% 的数据, n ≤ 1000 n≤1000 n≤1000
对于 100% 的数据, 2 ≤ n ≤ 100000 , 1 ≤ u , v ≤ n 2≤n≤100000,1≤u,v≤n 2≤n≤100000,1≤u,v≤n
题解
这道题其实就是求一个拓扑排序,在一个点没有度数后,把它的值置为子节点加1
代码如下:
#include<bits/stdc++.h>
using namespace std;
struct zz{
int idex,ans;
};
queue<zz> q;
vector<int> v[100005];
int f[100005],ans[100005];
bool flag[100005];
void BFS(int n){
for(int i=1;i<=n;i++){
if(f[i]<=1){
zz now;
now.ans=1;
now.idex=i;
q.push(now);
}
}
while(q.size()){
zz now;
now=q.front();
q.pop();
if(flag[now.idex]){
continue;
}
flag[now.idex]=1;
ans[now.idex]=now.ans;
for(int i=0;i<v[now.idex].size();i++){
f[v[now.idex][i]]--;
if(f[v[now.idex][i]]<=1){
zz nownow;
nownow.idex=v[now.idex][i];
nownow.ans=now.ans+1;
q.push(nownow);
}
}
}
}
int main(){
int n;
cin>>n;
for(int i=1;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
f[x]++;
f[y]++;
}
BFS(n);
for(int i=1;i<=n;i++){
printf("%d ",ans[i]);
}
return 0;
}