树的基操

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;
}

总结:全是送分题

以上是关于树的基操的主要内容,如果未能解决你的问题,请参考以下文章

liunx系统的基操命令2

JavaScript之基操

排序算法——简介

Mongodb3.6 基操命令——help有大用

基操勿 6 | Node.js 的异步I/O到底有多秀?

mysql基操