[省选前题目整理][BZOJ 2594]管道局长数据加强版(LCT)
来源:互联网 发布:单片机计数器实验报告 编辑:程序博客网 时间:2024/05/10 07:55
题目链接
http://www.lydsy.com/JudgeOnline/problem.php?id=2594
思路
很显然可以用LCT搞搞。。。正着做是删边,倒着做就是加边了。。。
而且可以发现,两个点之间最大边权最小的路径一定是在当前的MST上,因此我们离线把询问中删掉的边都无视掉后,在最后剩下的边里生成MST,并用一个LCT去维护这个MST,就是一条边看成LCT里的一个结点,MST上的一个点也看成LCT上的一个结点,一条边的两个端点对应的结点向这条边对应的结点连边,并且给每个边对应的结点打上路径最大值的tag,倒着从最后一个询问到第一个询问做,每次删边就变成了加边,如果当前要加入的边比这个边两端点路径上的最大边权要小,那么把那个最大边权的边在LCT里cut掉,然后link上当前要加入的边。
反正和NOI 2014魔法森林的LCT做法很像。。。个人认为LCT维护动态MST的做法非常经典。。。
另外此题还需要对边排序,并二分,得到每次删除询问要删的边的编号,我偷懒直接用的map,第一次交就TLE了,后来玩卡空间+卡时间过掉了,差点TLE+MLE,比标准的二分做法慢了4s,因此第一次做的同学们就别学我这做法了,2333
代码
#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <algorithm>#include <map>#define MAXN 1150000#define lson ch[o][0]#define rson ch[o][1]using namespace std;map<int,int>mp[100100];bool mark[MAXN];inline int getint(){ char ch = getchar(); for ( ; ch > '9' || ch < '0'; ch = getchar()); int tmp = 0; for ( ; '0' <= ch && ch <= '9'; ch = getchar()) tmp = tmp * 10 + int(ch) - 48; return tmp;}int ch[MAXN][2],fa[MAXN],val[MAXN],maxtag[MAXN],stack[MAXN],top=0;bool rev[MAXN];inline void pushup(int o){ maxtag[o]=o; if(val[maxtag[lson]]>val[maxtag[o]]) maxtag[o]=maxtag[lson]; if(val[maxtag[rson]]>val[maxtag[o]]) maxtag[o]=maxtag[rson];}inline void pushdown(int o){ if(!o) return; if(rev[o]) { rev[lson]^=1; rev[rson]^=1; swap(lson,rson); rev[o]=0; }}inline bool isRoot(int o){ return ch[fa[o]][0]!=o&&ch[fa[o]][1]!=o;}inline void rot(int x){ int y=fa[x],z=fa[y]; int p,q; if(ch[y][0]==x) p=0; else p=1; q=p^1; if(!isRoot(y)) { if(ch[z][0]==y) ch[z][0]=x; else ch[z][1]=x; } fa[x]=z,fa[y]=x; ch[y][p]=ch[x][q]; fa[ch[x][q]]=y; ch[x][q]=y; pushup(y); pushup(x);}inline void splay(int x){ top=0; stack[++top]=x; for(int i=x;!isRoot(i);i=fa[i]) stack[++top]=fa[i]; for(int i=top;i>=1;i--) pushdown(stack[i]); //!!!!!! while(!isRoot(x)) { int y=fa[x],z=fa[y]; if(!isRoot(y)) { if((ch[y][0]==x)==(ch[z][0]==y)) rot(y); else rot(x); } rot(x); }}inline void access(int x){ int tmp=0; while(x) { splay(x); ch[x][1]=tmp; pushup(x); tmp=x; x=fa[x]; }}inline void makeroot(int x){ access(x); splay(x); rev[x]^=1;}inline void link(int x,int y) //y是x父亲{ makeroot(x); fa[x]=y;}inline void cut(int x,int y) //y是x父亲{ makeroot(x); access(y); splay(y); ch[y][0]=fa[x]=0;}inline int query(int x,int y){ makeroot(x); access(y); splay(y); return maxtag[y];}int f[100100];inline int findSet(int x){ if(f[x]==x) return f[x]; return f[x]=findSet(f[x]);}struct edge{ int u,v,w;}edges[1000100];inline bool cmp(edge a,edge b){ return a.w<b.w;}int n,m,q;struct Query{ int x,y,cmd,ans;}querys[100100];int main(){ for(int i=0;i<MAXN;i++) f[i]=i; n=getint(),m=getint(),q=getint(); for(int i=1;i<=m;i++) edges[i].u=getint(),edges[i].v=getint(),edges[i].w=getint(); for(int i=1;i<=q;i++) querys[i].cmd=getint(),querys[i].x=getint(),querys[i].y=getint(); sort(edges+1,edges+m+1,cmp); for(int i=1;i<=m;i++) mp[edges[i].u][edges[i].v]=mp[edges[i].v][edges[i].u]=i; for(int i=1;i<=q;i++) if(querys[i].cmd==2) mark[mp[querys[i].x][querys[i].y]]=1; for(int i=1;i<=m;i++) //初始化LCT结点 { val[n+i]=edges[i].w; maxtag[n+i]=n+i; } int tot=0; //加的边的个数,为n-1时表明整个MST生成出来了 for(int i=1;i<=m;i++) { if(mark[i]) continue; int rootu=findSet(edges[i].u),rootv=findSet(edges[i].v); if(rootu!=rootv) { f[rootu]=rootv; link(edges[i].u,i+n); link(edges[i].v,i+n); tot++; if(tot==n-1) break; } } for(int i=q;i>=1;i--) { if(querys[i].cmd==1) querys[i].ans=val[query(querys[i].x,querys[i].y)]; else //加边操作 { int p=mp[querys[i].x][querys[i].y]; int tmp=query(querys[i].x,querys[i].y); if(val[tmp]>edges[p].w) { cut(edges[tmp-n].u,tmp); cut(edges[tmp-n].v,tmp); link(edges[p].u,p+n); link(edges[p].v,p+n); } } } for(int i=1;i<=q;i++) if(querys[i].cmd==1) printf("%d\n",querys[i].ans); return 0;}
0 0
- [省选前题目整理][BZOJ 2594]管道局长数据加强版(LCT)
- BZOJ 2594 [Wc2006]水管局长数据加强版 LCT
- 【BZOJ】【P2594】【Wc2006】【水管局长数据加强版】【题解】【LCT】
- [动态树 LCT] BZOJ 2594 [Wc2006]水管局长数据加强版
- bzoj 2594: [Wc2006]水管局长数据加强版(LCT+最小生成树+离线)
- BZOJ 2594: [Wc2006]水管局长数据加强版(LCT+最小生成树+离线)
- bzoj-2594 水管局长数据加强版
- 【BZOJ 2594】 [Wc2006]水管局长数据加强版
- BZOJ 2594: [Wc2006]水管局长数据加强版
- BZOJ 2594 [Wc2006]水管局长数据加强版
- bzoj 2594 [Wc2006]水管局长数据加强版
- [BZOJ2594][WC2006][LCT][MST]水管局长数据加强版
- 【最小生成树】【LCT】【bzoj2594】水管局长数据加强版
- [BZOJ2594][Wc2006][LCT]水管局长数据加强版
- [BZOJ2594][Wc2006]水管局长数据加强版(kruskal+lct)
- 【bzoj2594】【WC2006】【水管局长加强版】【lct】
- 2594: [Wc2006]水管局长数据加强版
- 2594: [Wc2006]水管局长数据加强版
- UVA - 10618(条件复杂的简单dp)
- Shell脚本常识--(特殊字符)
- 伯乐急寻千里马,够牛你就来。
- spring自定义标签和验证(validator)
- WinInet
- [省选前题目整理][BZOJ 2594]管道局长数据加强版(LCT)
- java SSLContext
- sqlite数据库详解
- mac 下终端的颜色配置
- 黑马程序员——网络编程
- ios电话号码验证
- Mybatis3配置文件解析
- Solr主从配置
- Linux那些事儿 之 戏说USB(12)接口是设备的接口(一)