为什么最后两个点 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;
}
}
//