题解:
lct维护最小生成树
首先,先对于每一条边,生成一个点,这个点连接这一条边的两个端点
点的值为边的权值
其他点的权值都是0
那么每一次查找i-j路径上面最小值,就变成查找树上路径点权最小值
按照最小生成树的方法来生成这一刻lct
然后先把所有要删去的边删掉,后面再一条一条加上去
代码:
#pragma GCC optimize(2) #include<bits/stdc++.h> using namespace std; const int N=2000005; int n,m,Q,top,f[N],fa[N],c[N][2],s[N],mx[N],val[N],rev[N]; struct edge{int u,v,w,id,d;}e[N/2]; struct que{int f,x,y,ans,id;}q[N/2]; int operator<(edge a,edge b){return a.u<b.u||(a.u==b.u&&a.v<b.v);} int cmp(edge a,edge b){return a.w<b.w;} int cmp2(edge a,edge b){return a.id<b.id;} int getf(int x){return x==f[x]?x:f[x]=getf(f[x]);} int find(int u,int v) { int l=1,r=m; while (l<r) { int mid=(l+r)/2; if (e[mid].u<u||(e[mid].u==u&&e[mid].v<v))l=mid+1; else r=mid; } return l; } int isroot(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;} void update(int x) { int l=c[x][0],r=c[x][1];mx[x]=x; if(val[mx[l]]>val[mx[x]])mx[x]=mx[l]; if(val[mx[r]]>val[mx[x]])mx[x]=mx[r]; } void rotate(int x) { int y=fa[x],z=fa[y],l,r; if(c[y][0]==x)l=0;else l=1;r=l^1; if (!isroot(y)) { if (c[z][0]==y)c[z][0]=x; else c[z][1]=x; } fa[x]=z;fa[y]=x;fa[c[x][r]]=y; c[y][l]=c[x][r];c[x][r]=y; update(y);update(x); } void pushdown(int x) { int l=c[x][0],r=c[x][1]; if (rev[x]) { rev[x]^=1;rev[l]^=1;rev[r]^=1; swap(c[x][0],c[x][1]); } } void down(int x) { if (!isroot(x))down(fa[x]); pushdown(x); } void splay(int x) { down(x); for (int y=fa[x];!isroot(x);rotate(x),y=fa[x]) if (!isroot(y))rotate((c[y][0]==x)==(c[fa[y]][0]==y)?y:x); } void access(int x) { int t=0; while (x) { splay(x); c[x][1]=t; update(x); t=x;x=fa[x]; } } void makeroot(int x){access(x);splay(x);rev[x]^=1;} void link(int x,int y){makeroot(x);fa[x]=y;} void cut(int x,int y){makeroot(x);access(y);splay(y);c[y][0]=fa[x]=0;} int query(int x,int y){makeroot(x);access(y);splay(y);return mx[y];} int read() { int x=0;char c; for (;c<'0'||c>'9';c=getchar()); for (;c>='0'&&c<='9';c=getchar())x=x*10+c-48; return x; } int main() { n=read();m=read();Q=read(); for (int i=1;i<=n;i++)f[i]=i; for (int i=1;i<=m;i++) { e[i].u=read(),e[i].v=read(),e[i].w=read(); if (e[i].u>e[i].v)swap(e[i].u,e[i].v); } sort(e+1,e+m+1,cmp); for (int i=1;i<=m;i++) { e[i].id=i; val[n+i]=e[i].w; mx[n+i]=n+i; } sort(e+1,e+m+1); for (int i=1;i<=Q;i++) { q[i].f=read(),q[i].x=read(),q[i].y=read(); if (q[i].f==2) { if(q[i].x>q[i].y)swap(q[i].x,q[i].y); int t=find(q[i].x,q[i].y); e[t].d=1;q[i].id=e[t].id; } } sort(e+1,e+m+1,cmp2); int tot=0; for (int i=1;i<=m;i++) if (!e[i].d) { int u=e[i].u,v=e[i].v,x=getf(u),y=getf(v); if (x!=y) { f[x]=y; link(u,i+n); link(v,i+n); } } for (int i=Q;i;i--) { int u=q[i].x,v=q[i].y,k=q[i].id; if(q[i].f==1)q[i].ans=val[query(u,v)]; else { int t=query(u,v); if(e[k].w<val[t]) { cut(e[t-n].u,t);cut(e[t-n].v,t); link(u,k+n);link(v,k+n); } } } for (int i=1;i<=Q;i++) if (q[i].f==1)printf("%d\n",q[i].ans); return 0; }