树的基操
Posted zzctommy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树的基操相关的知识,希望对你有一定的参考价值。
树的深度
求树的深度
#include<bits/stdc++.h>
using namespace std;
const int N=1000006;
vector<int>g[N];
int n,ans;
void dfs(int u,int fa,int dep)
{
ans=max(ans,dep);
for(int i=0;i<g[u].size();++i)
{
int v=g[u][i];
if(v==fa)continue;
dfs(v,u,dep+1);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
char c;
for(int j=1;j<=n;++j)
{
cin>>c;
if(c=='1')g[i].push_back(j),g[j].push_back(i);
}
}
dfs(1,-1,0);
printf("%d
",ans);
return 0;
}
树的宽度
求树的宽度
#include<bits/stdc++.h>
using namespace std;
const int N=1000006;
vector<int>g[N];
int n,ans,d[N];
void dfs(int u,int fa,int dep)
{
++d[dep];
for(int i=0;i<g[u].size();++i)
{
int v=g[u][i];
if(v==fa)continue;
dfs(v,u,dep+1);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
char c;getchar();
for(int j=1;j<=n;++j)
{
scanf("%c",&c);
if(c=='1')g[i].push_back(j);
}
}
dfs(1,-1,1);
for(int i=1;i<=n;++i)ans=max(ans,d[i]);
printf("%d
",ans);
return 0;
}
树节点孩子数
求树上每个节点的孩子数
#include<bits/stdc++.h>
using namespace std;
const int N=1000006;
vector<int>g[N];
int n,ans,d[N];
void dfs(int u,int fa,int dep)
{
++d[dep];
for(int i=0;i<g[u].size();++i)
{
int v=g[u][i];
if(v==fa)continue;
dfs(v,u,dep+1);
}
}
int main()
{
scanf("%d",&n);
g[1].push_back(0);
for(int i=1;i<=n;++i)
{
char c;getchar();
for(int j=1;j<=n;++j)
{
scanf("%c",&c);
if(c=='1')g[i].push_back(j);
}
}
for(int i=1;i<=n;++i)printf("%d ",g[i].size()-1);
return 0;
}
树的叶子节点
求树的叶子节点个数
#include<bits/stdc++.h>
using namespace std;
const int N=1000006;
vector<int>g[N];
int n,ans[N],d[N],tot;
void dfs(int u,int fa,int dep)
{
++d[dep];
for(int i=0;i<g[u].size();++i)
{
int v=g[u][i];
if(v==fa)continue;
dfs(v,u,dep+1);
}
}
int main()
{
scanf("%d",&n);
g[1].push_back(-1);
for(int i=1;i<=n;++i)
{
char c;getchar();
for(int j=1;j<=n;++j)
{
scanf("%c",&c);
if(c=='1')g[i].push_back(j);
}
}
for(int i=1;i<=n;++i)
if(g[i].size()==1)++ans[0],ans[++tot]=i;
printf("%d
",ans[0]);
for(int i=1;i<=tot;++i)
printf("%d ",ans[i]);
return 0;
}
树的重量
求一每个节点为根的子树大小
#include<bits/stdc++.h>
using namespace std;
const int N=1000006;
vector<int>g[N];
int n,size[N],tot;
void dfs(int u,int fa)
{
size[u]=1;
for(int i=0;i<g[u].size();++i)
{
int v=g[u][i];
if(v==fa)continue;
dfs(v,u);
size[u]+=size[v];
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<n;++i)
{
int x,y;
scanf("%d%d",&x,&y);
g[x].push_back(y);
g[y].push_back(x);
}
dfs(1,-1);
for(int i=1;i<=n;++i)printf("%d
",size[i]);
return 0;
}
树的直径
求树的直径长度
用2趟dfs跑出来的
#include<bits/stdc++.h>
using namespace std;
const int N=1000006;
vector<int>g[N];
int n,mx,mu;
void dfs(int u,int fa,int dis)
{
if(dis>mx){mx=dis;mu=u;}
for(int i=0;i<g[u].size();++i)
{
int v=g[u][i];
if(v==fa)continue;
dfs(v,u,dis+1);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<n;++i)
{
int x,y;
scanf("%d%d",&x,&y);
g[x].push_back(y);
g[y].push_back(x);
}
dfs(1,-1,0);
dfs(mu,-1,0);
printf("%d
",mx);
return 0;
}
树的重心
求以树的重心的最大子树大小
#include<bits/stdc++.h>
using namespace std;
const int N=1000006;
struct edge {
int nxt,to;
} e[N<<1];
int head[N],num_edge;
void add(int from,int to) {
++num_edge;
e[num_edge].nxt=head[from];
e[num_edge].to=to;
head[from]=num_edge;
}
int n,siz[N],rt,mn,sum;
void getrt(int u,int fa) {
int mx=0;siz[u]=1;
for(int i=head[u]; i; i=e[i].nxt) {
int v=e[i].to;
if(v==fa)continue;
getrt(v,u);
siz[u]+=siz[v];
mx=max(mx,siz[v]);
}
mx=max(mx,sum-siz[u]);
if(mx<mn)mn=mx,rt=u;
}
int main() {
scanf("%d",&n);
for(int i=1,x,y,w; i<n; ++i) {
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
sum=n;mn=n;getrt(1,0);
printf("%d
",mn);
return 0;
}
总结:全是送分题
以上是关于树的基操的主要内容,如果未能解决你的问题,请参考以下文章