BZOJ 2594: [Wc2006]水管局长数据加强版 【LCT维护最小生成树】

题目分析:

要明确一个事实:并查集删边是不存在的,不可能写的
所以离线之后把询问反过来做,变成加边 (这也是个老套路了)

对于删掉的边,用map存下它原来的编号
加回去的时候,询问(x,y)路径上的最大边权,看能否替换掉它。

但是众所周知LCT似乎只能维护点权。
那么就把边看作点,向两个端点连边,自身的点权就是边权。
由于替换的时候要断掉最大边,所以要保存点权最大的点的编号,而不是直接保存最大值。
询问就直接找到点权最大的那个点的编号,返回它的值。

然后就是板子了。
Code:

#include<cstdio>
#include<cctype>
#include<cstring>
#include<map>
#include<algorithm>
#define maxn 200005
using namespace std;
inline void read(int &a){
    char c;while(!isdigit(c=getchar()));
    for(a=c-'0';isdigit(c=getchar());a=a*10+c-'0');
}
inline void print(int a){
    if(a>=10) print(a/10);
    putchar(a%10+48);
}
int F[maxn];
int Find(int x){return x==F[x]?x:F[x]=Find(F[x]);}
namespace LCT{
    int ch[maxn][2],fa[maxn],pos[maxn],v[maxn],nb[maxn][2],tot;
    bool rev[maxn];
    #define il inline
    #define pa fa[x]
    il bool isc(int x){return ch[pa][1]==x;}
    il bool isr(int x){return ch[pa][0]!=x&&ch[pa][1]!=x;}
    il void pd(int x){
        if(rev[x]){
            swap(ch[x][0],ch[x][1]),rev[x]=0;
            rev[ch[x][0]]^=1,rev[ch[x][1]]^=1;
        }
    }
    il void pdpath(int x){if(!isr(x)) pdpath(pa);pd(x);}
    il void upd(int x){
        pos[x]=x;
        if(v[pos[ch[x][0]]]>v[pos[x]]) pos[x]=pos[ch[x][0]];
        if(v[pos[ch[x][1]]]>v[pos[x]]) pos[x]=pos[ch[x][1]];
    }
    il void rot(int x){
        int y=fa[x],z=fa[y],c=isc(x);
        if(!isr(y)) ch[z][ch[z][1]==y]=x;
        (ch[y][c]=ch[x][!c])&&(fa[ch[y][c]]=y);
        fa[ch[x][!c]=y]=x,fa[x]=z;
        upd(y),upd(x);
    }
    il void splay(int x){
        pdpath(x);
        for(;!isr(x);rot(x))
            if(!isr(pa)) rot(isc(pa)==isc(x)?pa:x);
    }
    il int access(int x,int y=0){
        for(;x;x=fa[y=x]) splay(x),ch[x][1]=y,upd(x);
        return y;
    }
    il void bert(int x){
        access(x),splay(x),rev[x]^=1;
    }
    il void link(int x,int y){
        bert(x),fa[x]=y;
    }
    il void cut(int x,int y){
        bert(x),access(y),splay(y);
        fa[x]=ch[y][0]=0;
        upd(y);
    }
    il int split(int x,int y){
        bert(x),access(y),splay(y);
        return y;
    }
    il void insert(int x,int y,int w){
        if(Find(x)!=Find(y)){
            v[++tot]=w,pos[tot]=tot;
            nb[tot][0]=x,nb[tot][1]=y;
            link(tot,x),link(y,tot);
            F[Find(x)]=Find(y);
            return;
        }
        int tmp=pos[split(x,y)];
        if(w<v[tmp]){
            cut(tmp,nb[tmp][0]),cut(tmp,nb[tmp][1]);
            v[tmp]=w,pos[tmp]=tmp,nb[tmp][0]=x,nb[tmp][1]=y;
            link(tmp,x),link(y,tmp);
        }
    }
    il int qmax(int x,int y){return v[pos[split(x,y)]];}
}
struct node{
    int x,y,z,tim;
    bool operator < (const node &p)const{return tim==p.tim?z<p.z:tim>p.tim;}
}e[maxn*5],q[maxn>>1];
map<int,int>id[maxn>>1];
int n,m,Q,cnt,idx,op,x,y,ans[maxn>>1];
char c;
int main()
{
    read(n),read(m),read(Q);
    for(int i=1;i<=m;i++){
        read(e[i].x),read(e[i].y),read(e[i].z);
        if(e[i].x>e[i].y) swap(e[i].x,e[i].y);
        id[e[i].x][e[i].y]=i;
    }
    for(int i=1;i<=Q;i++){
        read(op),read(x),read(y);if(x>y) swap(x,y);
        if(op==1) q[++cnt].x=x,q[cnt].y=y,q[cnt].tim=idx;
        else e[id[x][y]].tim=++idx;
    }
    for(int i=1;i<=m;i++) if(!e[i].tim) e[i].tim=idx+1;
    sort(e+1,e+1+m);
    int j=1;for(int i=1;i<=n;i++) F[i]=i;
    LCT::tot=n;//!!
    for(;e[j].tim==idx+1;j++) if(Find(e[j].x)!=Find(e[j].y)) LCT::insert(e[j].x,e[j].y,e[j].z);
    for(int i=cnt;i>=1;i--){
        for(;j<=m&&e[j].tim>q[i].tim;j++)
            LCT::insert(e[j].x,e[j].y,e[j].z);
        ans[i]=LCT::qmax(q[i].x,q[i].y);
    }
    for(int i=1;i<=cnt;i++) print(ans[i]),putchar('\n');

}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值