离线做,把删边转化为加边,那么如果加边的两个点不连通,直接连就行了.如果联通就找他们之间的瓶颈边,判断一下当前边是否更优,如果更优就cut掉瓶颈边,加上当前边.

那怎么维护瓶颈边呢?把边也看做点,向两个点分别连边,那么只用维护最大值就行了.维护的时候保存编号,比较的时候就比较编号对应的边权,这样方便询问时删边.

还有读入后注意储存 边(u,v)或者断边(u,v) 的时候,把较小值设为u,较大值设为v. 如果不这样的话在BZOJ上能A,但是在洛谷上会WA,因为BZOJ上的数据保证前面给出的边(u,v),在断边的时候给出的顺序仍然是(u,v).而洛谷上的官方数据可能给出的顺序是(v,u)

CODE(这个代码是加强版数据的范围)

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
template<typename T>inline void read(T &num) {
char ch; int flg = 1;
while((ch=getchar())<'0'||ch>'9')if(ch=='-')flg=-flg;
for(num=0;ch>='0'&&ch<='9';num=num*10+ch-'0',ch=getchar());
num*=flg;
}
const int N = 100005;
const int MAXN = 200005;
const int MAXM = 1000005;
const int MAXQ = 100005;
int n, m, Q;
struct edge { int u, v, len, id; bool po; }E[MAXM];
struct Query { int op, x, y, id; }q[MAXQ];
namespace LCT {
#define ls ch[x][0]
#define rs ch[x][1]
int ch[MAXN][2], fa[MAXN], mx[MAXN], w[MAXN], ID[MAXN];
bool rev[MAXN];
inline bool isr(int x) { return ch[fa[x]][0] != x && ch[fa[x]][1] != x; }
inline bool get(int x) { return x == ch[fa[x]][1]; }
inline void upd(int x) {
mx[x] = x;
if(ls && w[mx[ls]] > w[mx[x]]) mx[x] = mx[ls];
if(rs && w[mx[rs]] > w[mx[x]]) mx[x] = mx[rs];
}
inline void rot(int x) {
int y = fa[x], z = fa[y], l = get(x), r = l^1;
if(!isr(y)) ch[z][get(y)] = x;
fa[ch[x][r]] = y; fa[y] = x; fa[x] = z;
ch[y][l] = ch[x][r]; ch[x][r] = y;
upd(y), upd(x);
}
inline void mt(int x) { if(rev[x]) rev[x] ^= 1, rev[ls] ^= 1, rev[rs] ^= 1, swap(ls, rs); }
void mtpath(int x) { if(!isr(x)) mtpath(fa[x]); mt(x); }
inline void splay(int x) {
mtpath(x);
for(; !isr(x); rot(x))
if(!isr(fa[x])) rot(get(x)==get(fa[x])?fa[x]:x);
}
inline int access(int x) { int y=0;
for(; x; x=fa[y=x]) splay(x), ch[x][1]=y, upd(x);
return y;
}
inline void bert(int x) { access(x), splay(x), rev[x] ^= 1; }
inline int sert(int x) {
access(x), splay(x);
for(; ch[x][0]; x=ch[x][0]);
return x;
}
inline void link(int x, int y) {
bert(x);
if(sert(y) == x) return;
fa[x] = y;
}
inline void cut(int x, int y) {
bert(x), access(y), splay(y);
if(sert(y) != x || fa[x] != y || ch[x][1] != 0) return;
fa[x] = ch[y][0] = 0; upd(y);
}
inline int split(int x, int y) {
bert(x), access(y), splay(y);
return y;
}
inline int query(int x, int y) {
split(x, y);
if(sert(y) != x) return -1;
return mx[y];
}
}
using namespace LCT;
inline bool cmp1(const edge &i, const edge &j) { return i.len < j.len; }
inline bool cmp2(const edge &i, const edge &j) { return i.u == j.u ? i.v < j.v : i.u < j.u; }
inline bool cmp3(const edge &i, const edge &j) { return i.id < j.id; }
int f[N], tot;
int find(int x) { return f[x] == x ? x : f[x] = find(f[x]); }
inline void Kruskal() {
for(int i = 1; i <= n; ++i) f[i] = i;
sort(E + 1, E + m + 1, cmp3);
tot = 0;
for(int i = 1; i <= m; ++i)
if(!E[i].po) {
int x = find(E[i].u), y = find(E[i].v);
if(x != y) {
f[x] = y, ++tot;
mx[tot+n] = tot+n;
w[tot+n] = E[i].len;
ID[tot+n] = i;
link(E[i].u, n+tot);
link(E[i].v, n+tot);
if(tot == n-1) return;
}
}
}
inline int pos(int U, int V) { //二分找编号
int l = 1, r = m, mid;
while(l < r) {
mid = (l + r) >> 1;
if(E[mid].u < U || (E[mid].u == U && E[mid].v < V)) l = mid + 1;
else r = mid;
}
return l;
}
int ans[MAXQ];
int main () {
read(n), read(m), read(Q);
for(int i = 1; i <= m; ++i) {
read(E[i].u), read(E[i].v), read(E[i].len);
if(E[i].u > E[i].v) swap(E[i].u, E[i].v);
}
sort(E + 1, E + m + 1, cmp1);
for(int i = 1; i <= m; ++i) E[i].id = i;
sort(E + 1, E + m + 1, cmp2);
for(int i = 1; i <= Q; ++i) {
read(q[i].op), read(q[i].x), read(q[i].y);
if(q[i].x > q[i].y) swap(q[i].x, q[i].y);
if(q[i].op == 2) {
int k = pos(q[i].x, q[i].y);
q[i].id = E[k].id; E[k].po = 1;
}
}
Kruskal();
for(int i = Q; i >= 1; --i)
if(q[i].op == 1) ans[i] = w[query(q[i].x, q[i].y)];
else {
int t = query(q[i].x, q[i].y);
if(t == -1) { //不连通
++tot;
mx[n+tot] = n+tot; ID[n+tot] = q[i].id, w[n+tot] = E[q[i].id].len;
link(q[i].x, n+tot), link(q[i].y, n+tot);
}
else if(w[t] > E[q[i].id].len) {
cut(E[ID[t]].u, t), cut(E[ID[t]].v, t);
mx[t] = t; ID[t] = q[i].id; w[t] = E[q[i].id].len; //回收使用t这个编号,这样LCT的点数可以只开2*n
link(q[i].x, t), link(q[i].y, t);
}
}
for(int i = 1; i <= Q; ++i)
if(q[i].op == 1) printf("%d\n", ans[i]);
}

BZOJ 2594: [Wc2006]水管局长数据加强版 (LCT维护最小生成树)的更多相关文章

  1. BZOJ 2594: [Wc2006]水管局长数据加强版 [LCT kruskal]

    2594: [Wc2006]水管局长数据加强版 Time Limit: 25 Sec  Memory Limit: 128 MBSubmit: 2917  Solved: 918[Submit][St ...

  2. BZOJ 2594: [Wc2006]水管局长数据加强版( LCT )

    离线然后就是维护加边的动态MST, Link cut tree秒掉..不过我写+调了好久...时间复杂度O(NlogN + MlogM) ------------------------------- ...

  3. bzoj 2594: [Wc2006]水管局长数据加强版 动态树

    2594: [Wc2006]水管局长数据加强版 Time Limit: 25 Sec  Memory Limit: 128 MBSubmit: 934  Solved: 291[Submit][Sta ...

  4. bzoj 2594: [Wc2006]水管局长数据加强版

    Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一 ...

  5. BZOJ 2594: [Wc2006]水管局长数据加强版(kruskal + LCT)

    Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一 ...

  6. [BZOJ 2594] [Wc2006]水管局长数据加强版 【LCT】

    题目链接:BZOJ - 2594 题目分析 这道题如果没有删边的操作,那么就是 NOIP2013 货车运输,求两点之间的一条路径,使得边权最大的边的边权尽量小. 那么,这条路径就是最小生成树上这两点之 ...

  7. 【刷题】BZOJ 2594 [Wc2006]水管局长数据加强版

    Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一 ...

  8. bzoj 2594 [Wc2006]水管局长数据加强版(LCT+最小生成树)

    [深坑勿入] [给个链接] http://blog.csdn.net/popoqqq/article/details/41348549 #include<cstdio> #include& ...

  9. [bzoj2594][Wc2006]水管局长数据加强版 (lct)

    论蒟蒻的自我修养T_T.. 和noi2014魔法森林基本一样...然而数据范围大得sxbk...UPD:这题如果用lct判联通的话可能会被卡到O(mlogm)..所以最好还是用并查集吧 一开始数组开太 ...

随机推荐

  1. (三)mysql SQL 基本操作

    文章目录 MySQL服务器对象 mysql 的基本操作 SQL的注释 库操作 表(字段)操作 数据操作 MySQL服务器对象 mysql 服务器对象内部分成了 4 层: 系统(DBMS)----> ...

  2. Python【函数使用技巧】

    写成“子函数+主函数”的代码结构,也是因为每个不同的功能封装在单独的函数代码中,方便后续修改.增删 import math # 变量key代表循环运行程序的开关 key = 1 # 采集信息的函数 d ...

  3. python — 装饰器、迭代器

    目录 1 装饰器 2 迭代器 3 可迭代对象 1 装饰器 1.1目的.应用场景: 目的: 在不改变原函数内部代码的基础上,在函数执行前后自定义功能. 应用场景: 想要为函数扩展功能时,可以选择用装饰器 ...

  4. 华为精益敏捷专家:DevOps转型中的那些坑

    陈军--原腾讯高级项目经理.华为精益敏捷专家 DevOps是现在非常流行的一个词,很多人都在提DevOps,在往那个方向去转,但转的时候坑特别多. 现实是很理想的,大家都觉得做了DevOps之后就会非 ...

  5. MyBatis MyBatis Generator入门

    一.MGB功能简介 MyBatis Generator是一个代码生成工具. MBG是如何运行的呢?它会检查所连接到的数据库的一个或者多个table,然后生成可用来访问这些table的构建(Java代码 ...

  6. 尝试 javascript 一对多 双向绑定器

    <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8 ...

  7. python selenium4 模拟点击+拖动+保存验证码 测试对象+以验证码的返回ID保存命名 58同城验证码

    #!/usr/bin/python # -*- coding: UTF-8 -*- # @Time : 2019/12/5 17:30 # @Author : shenghao/10347899@qq ...

  8. 初学java4 编译器优化

    编译器自动转义 short/char/byte 在定义变量时,后面赋值小于边界值,即可自动转义 右侧值小于左侧范围,编译器直接强转 右侧值大于左侧范围,编译器报错 short a = 10+1; // ...

  9. YoloV3 训练崩溃

    经过排查  发现是这里出了问题 然后发现是标注文件里有 x=0 y=0  这样的数据,46_Jockey_Jockey_46_576.txt ,  那么肯定是标注文件出了问题!! 删除该标注文件即可. ...

  10. h5学习之表单

    <html> <head> <title>新型input类型及表单新元素</title> <meta charset="utf-8&qu ...