离线做,把删边转化为加边,那么如果加边的两个点不连通,直接连就行了.如果联通就找他们之间的瓶颈边,判断一下当前边是否更优,如果更优就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. Design Excel Sum Formula

    Your task is to design the basic function of Excel and implement the function of sum formula. Specif ...

  2. 【Funny Things】001——QQ循环发送消息

    借用Java的Robot类库中的键鼠模拟的方法,执行这个操作,首先切换到QQ界面,然后循环粘贴,回车发送消息. package newtest; import java.awt.*; import j ...

  3. 【LOJ】#2239. 「CQOI2014」危桥

    LOJ#2239. 「CQOI2014」危桥 就是先把每条边正着连一条容量为2的边,反着连一条容量为2的边 显然如果只有一个人走的话,答案就是一个源点往起点连一条容量为次数×2的边,终点往汇点连一个次 ...

  4. C# DataTable映射成Entity

    using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; ...

  5. 关于@JsonFormat(出参格式化)和@DateTimeFormat(入参格式化)

    背景: 从数据库查询获取数据时候  返回的json数据 日期会出现一串数字或者其他形式  和我们期待的不一样 如下图: 一开始使用@DateTimeFormat注解 但是输出结果和没有使用返回的jso ...

  6. S02_CH08_ ZYNQ 定时器中断实验

    S02_CH08_ ZYNQ 定时器中断实验 上一章实现了PS接受来自PL的中断,本章将在ZYNQ的纯PS里实现私有定时器中断.每隔一秒中断一次,在中断函数里计数加1,通过串口打印输出. 8.1中断原 ...

  7. Elastic Search快速上手(3):搜索

    前言 存储好数据之后,便可通过RESTful API进行搜索. 详细文档可参考: --简单搜索https://www.elastic.co/guide/cn/elasticsearch/guide/c ...

  8. BASE64 Encode Decode

    package com.humi.encryption; import java.io.IOException; import java.io.UnsupportedEncodingException ...

  9. Redis笔记一

    REmote DIctionary Server 是一个开源.内存存储的数据结构服务器,可以用作数据库来存储key-value数据,支持字符串,哈希表,列表,集合,位图,地理空间信息等数据类型,同时也 ...

  10. json树迭代

    getArray(data){ for (var i in data) { if(data[i].disabled){ data[i].disabled = false } if(data[i].ch ...