[题目链接]

https://www.lydsy.com/JudgeOnline/problem.php?id=2594

[算法]

首先离线 , 将删边操作转化为倒序加边

假设我们已经维护出了一棵最小生成树T , 若加入了一条边(u , v , w) , 那么形成了一个环 ,考虑kruskal算法的执行过程 :

若w < 环上的边权最大值 , 那么可以将(u , v , w)加入 , 并将环上边权最大的边删除

可以使用LCT维护

时间复杂度 : O(NlogN ^ 2) , 注意常数优化

[代码]

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 3e5 + ;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull; struct edge
{
int u , v , w;
} e[MAXN << ];
struct query
{
int type;
int u , v;
} que[MAXN << ]; int n , m , q;
int fa[MAXN];
bool flg[MAXN]; struct Link_Cut_Tree
{
struct Node
{
int father , son[] , mx , value , id;
bool tag;
} a[MAXN << ];
inline void update(int x)
{
a[x].mx = a[x].value;
a[x].id = x;
if (a[x].son[])
{
if (a[a[x].son[]].mx > a[x].mx)
{
a[x].mx = a[a[x].son[]].mx;
a[x].id = a[a[x].son[]].id;
}
}
if (a[x].son[])
{
if (a[a[x].son[]].mx > a[x].mx)
{
a[x].mx = a[a[x].son[]].mx;
a[x].id = a[a[x].son[]].id;
}
}
}
inline void init()
{
for (int i = n + ; i <= n + m + ; i++)
{
a[i].mx = a[i].value = e[i - n].w;
a[i].id = i;
}
}
inline void pushdown(int x)
{
if (a[x].tag)
{
swap(a[x].son[] , a[x].son[]);
a[a[x].son[]].tag ^= ;
a[a[x].son[]].tag ^= ;
a[x].tag = false;
}
}
inline bool get(int x)
{
pushdown(a[x].father);
return a[a[x].father].son[] == x;
}
inline bool nroot(int x)
{
return a[a[x].father].son[] == x | a[a[x].father].son[] == x;
}
inline void rotate(int x)
{
int f = a[x].father , g = a[f].father;
int tmpx = get(x) , tmpf = get(f);
int w = a[x].son[tmpx ^ ];
if (nroot(f)) a[g].son[tmpf] = x;
a[x].son[tmpx ^ ] = f;
a[f].son[tmpx] = w;
if (w) a[w].father = f;
a[f].father = x;
a[x].father = g;
update(f);
}
inline int find_root(int x)
{
access(x);
splay(x);
while (a[x].son[])
{
pushdown(x);
x = a[x].son[];
}
return x;
}
inline void access(int x)
{
for (int y = ; x; x = a[y = x].father)
{
splay(x);
a[x].son[] = y;
update(x);
}
}
inline void splay(int x)
{
int y = x , z = ;
static int st[MAXN];
st[++z] = y;
while (nroot(y)) st[++z] = y = a[y].father;
while (z) pushdown(st[z--]);
while (nroot(x))
{
int y = a[x].father , z = a[y].father;
if (nroot(y))
rotate((a[y].son[] == x) ^ (a[z].son[] == y) ? x : y);
rotate(x);
}
update(x);
}
inline void split(int x , int y)
{
make_root(x);
access(y);
splay(y);
}
inline void make_root(int x)
{
access(x);
splay(x);
a[x].tag ^= true;
pushdown(x);
}
inline void link(int x , int y)
{
make_root(x);
if (find_root(y) != x) a[x].father = y;
}
inline void cut(int x , int y)
{
make_root(x);
if (find_root(y) == x && a[x].father == y && !a[x].son[])
{
a[x].father = a[y].son[] = ;
update(y);
}
}
inline int query(int x)
{
return a[x].id;
}
} LCT; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
inline bool cmp(edge a , edge b)
{
return a.w < b.w;
}
inline int get_root(int x)
{
if (fa[x] == x) return x;
else return fa[x] = get_root(fa[x]);
} int main()
{ read(n); read(m); read(q);
for (int i = ; i <= m; i++)
{
read(e[i].u);
read(e[i].v);
read(e[i].w);
if (e[i].u > e[i].v) swap(e[i].u , e[i].v);
}
sort(e + , e + m + , cmp);
map< pair<int , int> , int> mp;
for (int i = ; i <= m; i++)
mp[make_pair(e[i].u , e[i].v)] = i;
for (int i = ; i <= q; i++)
{
read(que[i].type);
read(que[i].u);
read(que[i].v);
if (que[i].u > que[i].v) swap(que[i].u , que[i].v);
if (que[i].type == )
flg[mp[make_pair(que[i].u , que[i].v)]] = true;
}
LCT.init();
for (int i = ; i <= n; i++) fa[i] = i;
for (int i = ; i <= m; i++)
{
if (flg[i]) continue;
int su = get_root(e[i].u) , sv = get_root(e[i].v);
if (su != sv)
{
fa[su] = sv;
LCT.link(e[i].u , i + n);
LCT.link(e[i].v , i + n);
}
}
vector< int > ans;
for (int i = q; i >= ; i--)
{
if (que[i].type == )
{
LCT.split(que[i].u , que[i].v);
ans.push_back(e[LCT.query(que[i].v) - n].w);
} else
{
LCT.split(que[i].u , que[i].v);
int id = LCT.query(que[i].v);
if (e[mp[make_pair(que[i].u , que[i].v)]].w < e[id - n].w)
{
LCT.cut(e[id - n].u , id);
LCT.cut(e[id - n].v , id);
LCT.link(que[i].u , mp[make_pair(que[i].u , que[i].v)] + n);
LCT.link(que[i].v , mp[make_pair(que[i].u , que[i].v)] + n);
}
}
}
reverse(ans.begin() , ans.end());
for (unsigned i = ; i < ans.size(); i++) printf("%d\n" , ans[i]); return ;
}

[WC 2006] 水管局长的更多相关文章

  1. 数据结构(动态树):COGS 27. [WC 2006] 水管局长

    27. [WC 2006] 水管局长 ★★★☆   输入文件:tube.in   输出文件:tube.out   简单对比时间限制:3 s   内存限制:128 MB [问题描述 ] SC 省 MY ...

  2. [WC 2006]水管局长数据加强版

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

  3. 解题:WC 2006 水管局长

    题面 初见LCT,动态最小生成树+链上查询max,具体做法是把边转换成点(LCT只能维护点) 时光倒流,先把最后剩的连起来.然后查询就看链上最大值,修改看看链上最大值是否大于当前边,如果是就断开原来的 ...

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

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

  5. BZOJ2594: [Wc2006]水管局长数据加强版

    题解: 裸LCT+离线+二分+MST... 代码:(几乎摘抄自hzwer) #include<cstdio> #include<cstdlib> #include<cma ...

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

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

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

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

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

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

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

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

随机推荐

  1. 1、CRM2011编程实战——清空指定页签以下的全部选项,并对页签以下的指定控件进行操作

    需求:当页面载入时,"呼叫编号"保持不变,"任务号"自己主动更新."接报时间"和"发生日期"自己主动设置为当天日期和时间 ...

  2. 晶振及COMS电路

    COMS电路:http://www.docin.com/p-246885507.html 简介:无源晶振和有源晶振 电子线路中的晶体振荡器也分为无源晶振和有源晶振两种类型.无源晶振与有源晶振的英文名称 ...

  3. [笔记] 精通正则表达式/Mastering Regular Expressions

    / 匹配<emphasis>这个tag标注的IP地址的RE:‘<emphasis>([0-9]+(\.[0-9]+){3})</emphasis>' / 锚定--a ...

  4. Anacoda 介绍、安装、环境切换

    官网下载 概述 很多学习python的初学者甚至学了有一段时间的人接触到anaconda或者其他虚拟环境工具时觉得无从下手, 其主要原因就是不明白这些工具究竟有什么用, 是用来做什么的, 为什么要这么 ...

  5. 编码知识 (Unicode、UTF-8、ANSI)

    1. ASCII码 我们知道,在计算机内部,所有的信息最终都表示为一个二进制的字符串.每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte). ...

  6. remote connect openshift mysql

    再虚拟机内 rhc port-forward <app-name> 此时,可以在本机 访问 127.0.0.1:8080  登陆 网页, 3306连接sql https://unix.st ...

  7. StringUtils类使用 (转载)

    检查字符串是否为空或null或仅仅包含空格  String test = "";  String test1=" ";  String test2 = &quo ...

  8. Linux把查询结果写入到文本

    在Linux命令模式下,可以将查询结果写入文件.大概有两种方式,增量写入和覆盖写入. 增量写入: #iostat -m >> /tmp/iostat.txt 覆盖写入: #iostat - ...

  9. XML解析PULL

    解析xml是很经常使用的操作,除了SAX和DOM两种最经常使用的解析xml外,Pull解析器解析XML文件. 在Android的源代码中大量的使用Pull解析.pull不仅更加的面相对象,并且使用速度 ...

  10. EasyIPCamera通过RTSP协议接入海康、大华等摄像机,摒弃私有SDK接入弊端

    本文转自博客:http://blog.csdn.net/xinlanbobo/article/details/53156742 近期工作中需要开发一套视频监控系统,实现WEB端.手机APP端预览局域网 ...