树的子树大小与深度

2281 树的Size之和

51nod 2281

这题用的是并查集的思想,由于给定了父子关系,所以很容易知道建立并查集,最后find每个数,并且find函数找到一次某个节点,就给这个节点计数一次,代表这个节点有这个子节点

#include
using namespace std;
int num[1005],pre[1005];
void ans(int x)
{
	num[x]++;
	if(pre[x]==x) return;
	else ans(pre[x]);
}
int main()
{
	int T,m1,m2;
	scanf("%d",&T);
	for(int i=1;i<=T;i++){
		pre[i]=i;
	}
	for(int i=1;i<=T-1;i++){
		scanf("%d%d",&m1,&m2);
		pre[m2]=m1;
	}
	for(int i=1;i<=T;i++){
		ans(i);
	}
	int A=0;
	for(int i=1;i<=T;i++){
		A+=num[i];
	}
	cout<<A<<endl;
}

2627 树的深度及子树大小

这题和上面那题有些不同,首先他还需要求一个深度,而且他还没有给出父子关系,只给出了哪两个节点之间有边,选择用无向图的链式前向星存图,然后用dfs跑一遍图,边跑边记录深度和子树大小就行了

#include
using namespace std;
const int MAX=100005;
int head[MAX],depth[MAX],size[MAX];
struct
{
	int nxt,to;
}edge[MAX];
int cnt=1;
void add_edge(int u,int v)
{
	edge[cnt].to=v;
	edge[cnt].nxt=head[u];
	head[u]=cnt++;
}
int dfs(int x,int h)
{
	depth[x]=h;
	int lu=1;
	for(int i=head[x];i;i=edge[i].nxt){
		int v=edge[i].to;
		if(depth[v]) continue;
		lu+=dfs(v,h+1);
	}
	return (size[x]=lu);
}
int duru()
{
	int T,m1,m2;
	scanf("%d",&T);
	for(int i=1;i<=T-1;i++){
		scanf("%d%d",&m1,&m2);
		add_edge(m1,m2);
		add_edge(m2,m1);
	}
	return T;
}
void shuchu(int T)
{
	for(int i=1;i<=T;i++){
		cout<<depth[i]<<' ';
	}
	cout<<endl;
	for(int i=1;i<=T;i++){
		cout<<size[i]<<' ';
	}
}
int main()
{
	int num=duru();
	dfs(1,1);
	shuchu(num);
}

你可能感兴趣的:(#,ACM——图论)