[省选前题目整理][BZOJ 2594]管道局长数据加强版(LCT)
2015-03-24 16:27
357 查看
题目链接
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; }
相关文章推荐
- BZOJ 2594: [Wc2006]水管局长数据加强版(kruskal + LCT)
- [BZOJ 2594] [Wc2006]水管局长数据加强版 【LCT】
- [BZOJ2594][WC2006][LCT][MST]水管局长数据加强版
- BZOJ2594 [Wc2006]水管局长数据加强版 【LCT维护最小生成树】
- [bzoj2594][Wc2006]水管局长数据加强版——lct+离线
- [BZOJ2594] [Wc2006]水管局长数据加强版(LCT + kruskal + 离线)
- BZOJ 2594: [Wc2006]水管局长数据加强版 [LCT kruskal]
- [BZOJ2594][Wc2006]水管局长数据加强版(kruskal+lct)
- bzoj 2594 [Wc2006]水管局长数据加强版(LCT+最小生成树)
- [BZOJ2594][Wc2006][LCT]水管局长数据加强版
- BZOJ_2594_[Wc2006]水管局长数据加强版_LCT
- 【最小生成树】【LCT】【bzoj2594】水管局长数据加强版
- BZOJ 2594: [Wc2006]水管局长数据加强版(LCT+最小生成树+离线)
- [bzoj2594][Wc2006]水管局长数据加强版 (lct)
- bzoj 2594: [Wc2006]水管局长数据加强版(LCT+最小生成树+离线)
- BZOJ 2594 [Wc2006]水管局长数据加强版 LCT
- [动态树 LCT] BZOJ 2594 [Wc2006]水管局长数据加强版
- BZOJ 2594: [Wc2006]水管局长数据加强版( LCT )
- [BZOJ2594][WC2006]水管局长数据加强版(LCT维护最小生成树)
- BZOJ-2594 水管局长数据加强版 Link-Cut-Tree+Kruskal+乱搞inline