版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
2281 树的Size之和
这题用的是并查集的思想,由于给定了父子关系,所以很容易知道建立并查集,最后find每个数,并且find函数找到一次某个节点,就给这个节点计数一次,代表这个节点有这个子节点
#include<iostream>
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<iostream>
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);
}