Time:2016.05.10
Author:xiaoyimi
转载注明出处谢谢


传送门
思路:
LCT维护路径最小值
倒叙处理询问,就相当于往图里面加边。
实时维护最小值,即最小生成树,可以参照魔法森林。
最初的最小生成树操作用kruskal
最蛋疼的是处理询问时你不知道要删除哪条边,这给kruskal带来很大麻烦,所以我们对原来的每一条边使其编号小的端点在前,大的在后,然后以左端点为第一关键字,右端点为第二关键字排序,记录下每个左端点的所在区间,然后就可以通过二分查找的方式来确定是哪条边了
LCT操作时把边当成带有权值的点,每次处理询问时看两点是否联通,不连通就连上,连通就寻找路径上的最大值,两者比较取较小即可,连通性用并查集维护(LCT其实也可以,不过复杂度略大)
注意:
说起来容易做起来难,这道题调了我好久!是一道可以练习码力的题目!
代码:

#include<bits/stdc++.h>
using namespace std;
#define N 100003
#define M 1000003
int in()
{int t=0;char ch=getchar();while (!isdigit(ch)) ch=getchar();while (isdigit(ch)) t=(t<<3)+(t<<1)+ch-48,ch=getchar();return t;
}
int n=in(),m=in(),k=in();
int belong[N],L[N],R[N],ans[N],stacks[N+M],X[M],Y[M];
bool vis[M];
struct edge
{int id,u,v,w;void swaps(){if (u>v) swap(u,v);}
}e[M];
struct LCT
{int data,maxn,ch[2],fa;bool lazy;
}a[M+N];
struct question
{int opt,x,y,id,w;void swaps(){if (x>y) swap(x,y);}
}q[N];
bool cmp1(edge x,edge y)
{if (x.u==y.u) return x.v<y.v;return x.u<y.u;
}
bool cmp2(edge x,edge y){return x.w<y.w;}
int find(int x)
{if (belong[x]!=x) belong[x]=find(belong[x]);return belong[x];
}
edge search(int l,int r,int data)
{int mid;while (l<=r){mid=l+r>>1;if (e[mid].v==data) return e[mid];if (e[mid].v>data) r=mid-1;else l=mid+1;}
}
void ct(int x)
{int l=a[x].ch[0],r=a[x].ch[1];a[x].maxn=(a[a[l].maxn].data>a[a[r].maxn].data?a[l].maxn:a[r].maxn);a[x].maxn=(a[a[x].maxn].data>a[x].data?a[x].maxn:x);
}
void pushdown(int x)
{if (!a[x].lazy) return;a[a[x].ch[0]].lazy^=1;a[a[x].ch[1]].lazy^=1;swap(a[x].ch[0],a[x].ch[1]);a[x].lazy=0;
}
bool isroot(int x)
{return a[a[x].fa].ch[0]!=x&&a[a[x].fa].ch[1]!=x;
}
void rorate(int x,bool mk)
{int y=a[x].fa;a[x].fa=a[y].fa;if (!isroot(y)){if (a[a[y].fa].ch[0]==y) a[a[y].fa].ch[0]=x;else a[a[y].fa].ch[1]=x;}a[y].ch[!mk]=a[x].ch[mk];a[a[x].ch[mk]].fa=y;a[y].fa=x;a[x].ch[mk]=y;ct(y);ct(x);
}
void splay(int x)
{int y,cnt=0,k=x;stacks[++cnt]=k;while (!isroot(k)) k=a[k].fa,stacks[++cnt]=k;for (int i=cnt;i;i--) pushdown(stacks[i]);while (!isroot(x)){y=a[x].fa;if (isroot(y)){if (a[y].ch[0]==x) rorate(x,1);else rorate(x,0);}else if (a[a[y].fa].ch[0]==y){if (a[y].ch[0]==x) rorate(y,1);else rorate(x,0);rorate(x,1);}else{if (a[y].ch[1]==x) rorate(y,0);else rorate(x,1);rorate(x,0);}}
}
void access(int x)
{for (int y=0;x;y=x,x=a[x].fa)splay(x),a[x].ch[1]=y,ct(x);
}
void link(int x,int y)
{access(x);splay(x);a[x].lazy^=1;a[x].fa=y;splay(x);
}
void cut(int x,int y)
{access(x);splay(x);a[x].lazy^=1;access(y);splay(y);a[x].fa=a[y].ch[0]=0;ct(y);
}
int ask(int x,int y)
{access(x);splay(x);a[x].lazy^=1;access(y);splay(y);return a[y].maxn;
}
main()
{for (int i=0;i<=n;i++)belong[i]=i;for (int i=1;i<=m;i++)e[i]=(edge){i,in(),in(),in()},a[i+n].data=e[i].w,e[i].swaps(),X[i]=e[i].u,Y[i]=e[i].v;for (int i=1;i<=k;i++)q[i].opt=in(),q[i].x=in(),q[i].y=in(),q[i].swaps();sort(e+1,e+m+1,cmp1);L[e[1].u]=1;for (int i=1;i<m;i++)if (e[i].u!=e[i+1].u) R[e[i].u]=i,L[e[i+1].u]=i+1;R[e[m].u]=m;edge re;for (int i=1;i<=k;i++)if (q[i].opt==2)re=search(L[q[i].x],R[q[i].x],q[i].y),q[i].id=re.id,q[i].w=re.w,vis[q[i].id]=1;sort(e+1,e+m+1,cmp2);int t=0;for (int i=1;i<=m;i++)if (!vis[e[i].id]){int f1=find(e[i].u),f2=find(e[i].v);if (f1!=f2){belong[f1]=f2;link(e[i].u,e[i].id+n);link(e[i].v,e[i].id+n);if (++t==n-1) break;}}for (int i=k;i;i--)if (q[i].opt==2){int t=ask(q[i].x,q[i].y);if (a[t].data>q[i].w)cut(X[t-n],t),cut(Y[t-n],t),link(q[i].x,q[i].id+n),link(q[i].y,q[i].id+n);}elseans[++ans[0]]=a[ask(q[i].x,q[i].y)].data;for (int i=ans[0];i;i--) printf("%d\n",ans[i]);
}

【BZOJ2594】水管局长加强版,LCT+并查集+二分查找位置相关推荐

  1. bzoj 2959: 长跑(LCT+并查集)

    2959: 长跑 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 315  Solved: 178 [Submit][Status][Discuss] ...

  2. 并查集+二分-hdu-4750-Count The Pairs

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4750 题目大意: 给一无向图,n个点,m条边,每条边有个长度,且不一样.定义f(i,j)表示从节点i ...

  3. HDU 3081 Marriage Match II (并查集+二分+最大流 | 并查集+二分图匹配)

    题意:n 个男生.n个女生玩游戏,每个女生都可以和她不讨厌的男生结婚,此外她的朋友如果也不讨厌这个男生,也可以和他结婚:对于女生,如果A和B是朋友,B和C是朋友,那么A和C也是朋友.每次游戏女生会找一 ...

  4. 使用并查集实现查找无向图的连通分量和求解有向图的强连通分量

    目录 1.无向图的连通分量 2.求解连通分量算法的实现 3.有向图的强连通分量 4.求解有向图的强连通分量 使用C语言实现并查集 有向图和无向图 1.无向图的连通分量 无向图G中,如果存在从顶点v1到 ...

  5. [BZOJ3669]-[Noi2014]魔法森林-LCT+并查集

    说在前面 刚刚去写了一道SPFA+网络流的糅合题,1A了 闲着没事干开始翻起了status,发现有人在做水管局长,哇这不是LCT嘛! 然后回头看了一下自己写过的寥寥无几的LCT的题,发现都快要忘了 于 ...

  6. [bzoj4998][LCT][并查集]星球联盟

    Description 在遥远的S星系中一共有N个星球,编号为1-N.其中的一些星球决定组成联盟,以方便相互间的交流.但是,组成 联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条 ...

  7. 【2018.5.19】模拟赛之四-ssl2435 航空公司【并查集,二分】

    正题 题目大意 有n个点,给出坐标,选择所有距离在k之内的边要求联通所有点,求最小的k. 解题思路 垃圾解法 用二分答案然后加并查集求是否联通. 时间复杂度:O(mlogn)O(mlogn)O(mlo ...

  8. P1396 营救(并查集+二分)

    思路:检验函数中,先初始化每个节点的下标,每调用检验函数就从新使用一次并查集(并查集的时间复杂度非常低),然后,就看当一条路的价值val<=假设最大值x时,就把他们连接起来. #include& ...

  9. POJ-2985(树状数组 + 并查集 + 二分)

    题目:http://poj.org/problem?id=2985 这题考察了两个点呢,组合并用到了并查集,求第K大的数用到了树状数组,刚开始WA了几次,发现是在组合并之后仅仅update(*, -1 ...

最新文章

  1. 工艺技术:14nm与28nm工艺
  2. 一堆让人惊喜的实用工具,也许你还不知道
  3. 用于python环境下的数据操作_数据分析(一):环境搭建,以及初步操作文件
  4. 吴恩达 coursera ML 第九课总结+作业答案
  5. 学习一种新编程语言要做的15个练习
  6. mysql查询优化以及面试小结
  7. 【电路原理】学习笔记(1):电路模型的基本变量
  8. Spring Boot2.0+中,自定义配置类扩展springMVC的功能
  9. from表单提交和JSON区别
  10. matlab基于dct的图像压缩编码解码_音频压缩编码的基本原理详解
  11. 平凡而又神奇的贝叶斯方法(转)
  12. 概率论与数理统计大纲
  13. 什么叫结构化程序设计,他的主要内容是什么?
  14. Mysql Workbench SSL错误
  15. 解决AS3.5在oppo系统更新后无法打包apk问题
  16. hyperlynx si 前仿真
  17. 基于QT的网络嗅探器实现(网络安全课程设计)
  18. Windows驱动之IRP PENDING
  19. python x%y_Python运算符
  20. MAC下配置芯片为CH340T的USB转串口接口的注意事项

热门文章

  1. 程序员一定要知道的11个实用工具网站
  2. 华为张顺茂:迎接拐点,拥抱计算新架构
  3. 【Python3网络爬虫开发实战】3.1-使用urllib
  4. HDFView 3.1.2 在WIN10系统安装后打开出现黑框闪退的解决方法
  5. LeetCode-76: 最小覆盖子串
  6. 回望2019,展望2020
  7. Python面向对象的基本实现
  8. 基于C语言、线性表的 二、八、十、十六进制转换 及 加运算、左右移位运算、乘法运算 的科学计算器设计
  9. linux 网络命令 dns,[LN_03] Linux网络环境查看(网卡|路由|DNS|IP)、网络测试命令(端口探测|路由跟踪|抓包|ssh连接)...
  10. nginx php 源码安装,Nginx和php安装及配置一之编译安装nginx-1.8.0