关于树剖LCA
查看原帖
关于树剖LCA
374893
randnameaaa楼主2022/11/3 16:47

为什么最后两个点 MLE 了啊,是树剖占的空间太大,还是我的写法有问题?

方法是 Kruskal 重构树 + 树剖 LCA

#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e5+5,M=3e5+5;
int n,m,q,w[N<<1],cnt;
struct node{
    int l,r,val;
    bool operator<(const node w)const{
        return val<w.val;
    }
}a[M];
int fa[N<<1];
int he[N<<1],ne[M],go[M],tot;
inline void add(int a,int b){
    ne[++tot]=he[a];he[a]=tot;go[tot]=b;
    ne[++tot]=he[b];he[b]=tot;go[tot]=a;
}
inline int find(int x){
    if(x!=fa[x]) return fa[x]=find(fa[x]);
    else return x;
}
inline void exkruskal(){
    cnt=n;
    for(int i=1;i<=m;i++){
        int A=find(a[i].l),B=find(a[i].r);
        if(A!=B){
            w[++cnt]=a[i].val;
            fa[A]=cnt;fa[B]=cnt;
            add(cnt,A);add(cnt,B);
            if(cnt==2*n-1) break;
        }
    }
} 
int dep[N],f[N],si[N],son[N],top[N];
bool dfn[N];
inline void dfs1(int u,int p){
    dep[u]=dep[p]+1;f[u]=p;
    si[u]=1;
    for(int i=he[u];i;i=ne[i]){
        int v=go[i];
        if(v==p) continue;
        dfs1(v,u);
        si[u]+=si[v];
        if(si[son[u]]<si[v]) son[u]=v;
    }
}
inline void dfs2(int u,int tp){
    top[u]=tp;
    dfn[u]=1;
    if(son[u]) dfs2(son[u],tp);
    else return ;
    for(int i=he[u];i;i=ne[i]){
        int v=go[i];
        if(v==son[u]||v==f[u]) continue;
        dfs2(v,v);
    }
}
inline int lca(int x,int y){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])
            swap(x,y);
        x=f[top[x]];
    }
    return dep[x]<dep[y]?x:y;
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=2*n;i++)
        fa[i]=i;
    for(int i=1;i<=m;i++)
        cin>>a[i].l>>a[i].r>>a[i].val;
    sort(a+1,a+m+1);
    exkruskal();
//    dfs1(cnt,0);
//    dfs2(cnt,cnt);
    for(int i=cnt;i>=1;i--) 
        if(!dfn[i]){
            dfs1(i,0);
            dfs2(i,i);
        }
    cin>>q;
    while(q--){
        int u,v;
        cin>>u>>v;
        if(find(u)!=find(v)){
            cout<<"impossible"<<endl;
            continue ;
        }
        int LCA=lca(u,v);
        cout<<w[LCA]<<endl;
    }
}
//
2022/11/3 16:47
加载中...