[SinGuLaRiTy] 复习模板-树

Posted SinGuLaRiTy2001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[SinGuLaRiTy] 复习模板-树相关的知识,希望对你有一定的参考价值。

【SinGuLaRiTy-1041】 Copyright (c) SinGuLaRiTy 2017. All Rights Reserved.

计算树的直径

//方法:任选一个点作为起点进行一次BFS,找到最远点u。再以u为起点做一次BFS,找最长路即直径。
queue<int>point;
void bfs(int a,int dis[])
{
    memset(dis,inf,sizeof dis);
    dis[a]=0;
    point.push(a);
    int v ,u ;
    while(!point.empty())
    {
        u=point.front();
        point.pop();
        for(node *p=adj[u];p!=NULL;p=p->next)
            if(dis[(v=p->v)]>dis[u]+p->w)
            {
                dis[v]=dis[u]+p->w;
                point.push(v);
            }
    }
}

void solve()//输出直径长度
{
    bfs(1,dis);
    int flag=1;
    for(int i=2;i<=n;++i)
        if(dis[flag]<dis[i])
            flag=i;
    bfs(flag,dis2);
    int flag2=1;
    for(int i=2;i<=n;++i)
        if(dis2[flag2]<dis2[i])
            flag2=i;
    printf("%d",dis2[flag2]);
}

LCA-返回a,b两点间的最短边权

返回a,b两点之间的最短边权
void dfs(int u)
{
    int v ;
    for(node *p=adj[u];p!=NULL;p=p->next)
    {
        v=p->v;
        f[v][0]=u ;
        dep[v]=dep[u]+1 ;
        dfs(v);
    }
}

void init()
{
    dep[root]=0 ;
    dfs(root);
    f[root][0]=root ;
    for(int j=1;j<MAXK;++j)
        for(int i=1;i<=n;++i)
            f[i][j]=f[f[i][j-1]][j-1];
}

void adjust(int &u,int val)
{
    for(int j=MAXK-1;j>=0;--j)
        if(dep[f[u][j]]>=val)
            u=f[u][j];
}

int solve(int u,int v)
{
    if(dep[u]>dep[v])adjust(u,dep[v]);
    else if(dep[u]<dep[v])adjust(v,dep[u]);
    if(u==v)return u;
    for(int j=MAXK-1;j>=0;--j)
        if(f[u][j]!=f[v][j])
            u=f[u][j] ,v=f[v][j];
    return f[u][0];
}

LCA-tarjan算法

void tarjan(int u)
{
    for(node *p=adj[u];p!=NULL;p=p->next)
    {
        tarjan(p->v);
        Union(p->v,u);
    }
    vis[u]=1;
    
    for(int i=1;i<=ask[u][0];++i)
        if(vis[ask[u][i]]==1)
            printf("%d\n",getroot(ask[u][i]));
}

void init()
{
    scanf("%d",&m);
    while(m--)
    {
        scanf("%d%d",&a,&b);
        ask[a][++ask[a][0]]=b;
        ask[b][++ask[b][0]]=a;
    }
    for(int i=1;i<=n;++i)
        if(!in[i])
        {
            tarjan(i);
            break;
        }
}

 

以上是关于[SinGuLaRiTy] 复习模板-树的主要内容,如果未能解决你的问题,请参考以下文章

[SinGuLaRiTy] 复习模板-搜索

[SinGuLaRiTy] 复习模板-数学

[SinGuLaRiTy] 数论题目复习

[SinGuLaRiTy] 贪心题目复习

[SinGuLaRiTy] 分治题目复习

[SinGuLaRiTy] 图论题目复习