问大家一个形式上的问题
查看原帖
问大家一个形式上的问题
836104
cxlian25楼主2023/1/10 22:41

我写了一个树链剖分,发现和别人不太一样

#include <bits/stdc++.h>
using namespace std;
const int N=5e5+3;
int n,m,s;
int fa[N],dep[N],siz[N],hson[N],dfn[N],rnk[N],top[N],cnt=0;
vector<int>edge[N];
void dfs(int x,int f,int d){
    hson[x]=0;dep[x]=d;fa[x]=f;siz[x]=1;
    for(int i=0;i<edge[x].size();i++){
        int to=edge[x][i];
        if(to==f)continue;
        dfs(to,x,d+1);
        siz[x]+=siz[to];
        if(!hson[x]||siz[to]>siz[hson[x]])
            hson[x]=to;
    }
}
void dfs2(int x,int f,int t){
    dfn[x]=++cnt;rnk[cnt]=x;top[x]=t;
    if(!hson[x])return;
    dfs2(hson[x],x,t);
    for(int i=0;i<edge[x].size();i++){
        int to=edge[x][i];
        if(to==f||to==hson[x]){
            continue;
        }
        dfs2(to,x,to);
    }
}
int lca(int x,int y){
    while(top[x]!=top[y]){
        if(dep[top[x]]>=dep[top[y]]){
            x=fa[top[x]];
        }
        else y=fa[top[y]];
    }
    if(dep[x]>=dep[y])return y;
    return x;
}
int main(){
    scanf("%d%d%d",&n,&m,&s);
    for(int i=1;i<n;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
    dfs(s,0,1);
    dfs2(s,0,s);
    while(m--){
        int x,y;
        scanf("%d%d",&x,&y);
        printf("%d\n",lca(x,y));
    }
    return 0;
}

哪里不一样呢,就是邻接表存边的时候,别人一般结构体里两个值,一个起点一个终点嘛,再来一个全局变量计数,我这是什么呢,我这edge[i].push_back(j) 的时候,表示序号为i的节点有一个序号为j的边。存边的时候存两边就可以了,开数组没必要双倍,我发现和别人都不一样,各有利弊吧(比如比着题解调试的时候不方便),有没有大佬分析一下这个形式的差异

2023/1/10 22:41
加载中...