广义圆方树

本文通过三个例题——P4320 道路相遇、P4606 战略游戏和 CF Round #278 Tourists,详细探讨了在解决树上问题时,树剖与倍增算法的效率对比。在面对复杂问题时,树剖在处理速度上的优势得到了体现。
摘要由CSDN通过智能技术生成

一、例题①:P4320 道路相遇
可能是因为把树封装了,倍增怎么写都超时。
不过倍增确实慢,树剖快好多。
在这里插入图片描述

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<queue>
#define ll long long
#define pr make_pair
#define pb push_back
//#define lc (p<<1)
//#define rc (p<<1|1)
using namespace std;


char buffer[100001],*S,*T;
inline char Get_Char()
{
   
    if (S==T)
    {
   
        T=(S=buffer)+fread(buffer,1,100001,stdin);
        if (S==T) return EOF;
    }
    return *S++;
}
inline int read()
{
   
    char c;int re=0;
    for(c=Get_Char();c<'0'||c>'9';c=Get_Char());
    while(c>='0'&&c<='9') re=re*10+(c-'0'),c=Get_Char();
    return re;
}




const int inf=0x3f3f3f3f;
const ll lnf=0x3f3f3f3f3f3f3f3f;
const double dnf=1e15;
const int mod=1e9+7;
const int maxn=4000100;
int dfn[maxn],low[maxn],st[maxn];
int cnt=0,tp=0,n,m,q,cntf;
int d[maxn],f[maxn],son[maxn],si[maxn];
int id[maxn],top[maxn];

struct Tree
{
   
    int head[maxn],ver[maxn],nt[maxn];
    int tot=1;
    void add(int x,int y)
    {
   
        ver[++tot]=y,nt[tot]=head[x],head[x]=tot;
    }
}yy,yf;


void dfs(int x)
{
   
    dfn[x]=low[x]=++cnt;
    st[++tp]=x;

    for(int i=yy.head[x];i;i=yy.nt[i])
    {
   
        int y=yy.ver[i];
        if(!dfn[y])
        {
   
            dfs(y);
            low[x]=min(low[x],low[y]);
            if(low[y]>=dfn[x])
            {
   
                cntf++;
                yf.add(cntf,x);
                yf.add(x,cntf);
                int z;
                do
                {
   
                    z=st[tp--];
                    yf.add(cntf,z);
                    yf.add(z,cntf);
                }while(z!=y);
            }
        }
        else low[x]=min(low[x],dfn[y]);
    }

}

void dfs1(int x,int fa)
{
   
    int max_son=0;
    si[x]=1;
    for(int i=yf.head[x];i;i=yf.nt[i])
    {
   
        int y=yf.ver[i];
        if(y==fa) continue;
        d[y]=d[x]+1;
        f[y]=x;
        dfs1(y,x);
        si[x]+=si[y];
        if(si[y]>max_son) max_son=si[y],son[x]=y;
    }
}

void dfs2(int x,int t)
{
   
    top[x]=t;
    id[x]=++cnt;
    if(!son[x]) return ;
    dfs2(son[x],t);
    for(int i=yf.head[x];i;i=yf.nt[i])
    {
   
        int y=yf.ver[i];
        if(y!=son[x]&&y!=f[x])
            dfs2(y,y);
    }
}

int lca(int x,int y)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值