To_Heart—题解——叶子清除计划

题目描述

⼩Y同学是⼀位数据结构⼤师同时也是⼀位园艺⼤师。

秋天到了,⼩Y同学需要对学校内的⼀棵树展现他顶尖的修叶⽔平。

学校内的这棵树是⼀颗拥有 n n n个点的⽆根树,每次⼩Y会删去所有的叶⼦节点(即度数小于等于1的节点),直到所有的点都被删除了为⽌。

⼩Y现在想问你对于每个点,求出它是第⼏次操作中被删除的。

输入格式

第⼀⾏⼀个数字 n n n,表⽰树上节点个数

接下来 n − 1 n−1 n1⾏,每⾏两个数字 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

样例一.png

样例输入2:

4
1 2
1 3
1 4

样例输出2:

2 1 1 1

样例二.png

数据范围与提示

对于 30% 的数据, n ≤ 1000 n≤1000 n1000

对于 100% 的数据, 2 ≤ n ≤ 100000 , 1 ≤ u , v ≤ n 2≤n≤100000,1≤u,v≤n 2n100000,1u,vn

题解

这道题其实就是求一个拓扑排序,在一个点没有度数后,把它的值置为子节点加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;
}
posted @ 2020-09-27 20:54  To_Heart  阅读(23)  评论(0编辑  收藏  举报