首先声明,这份代码空间复杂度 \(O(n^2)\),瓶颈在给边打标记

由于博主太菜,懒得再改成低复杂度的打标记了,所以\(BZOJ\)的数据过不去

Description

link

给一张图,会有删边操作,求当前图路径\((x,y)\) 的最大边权

\(n \leq 10^3 ,m \le 10^5\)

或\(BZOJ\)版:\(n\le 10^5,m\le10^6\)

Solution

\[Begin
\]

明确两点:

1.这个题要\(LCT\)(因为有删边的操作)

2.这个题把询问离线下来,然后逆序加边更可做

这个题中LCT维护的是“边权”

这里有一个点边转化:

把每一个边拆成点,对端点连两条边(边权就是\(e[i].dis\)),这样就可以维护点权了,在\(link\)和\(cut\)操作中有点点不同

如下:

cut(e[tmp - n].from, tmp);
cut(e[tmp - n].to, tmp);
link(x[i], id[x[i]][y[i]] + n);
link(y[i], id[x[i]][y[i]] + n);

先给出图的最终态,然后求一个最小生成树

每个操作先打通链,也就是 \(split\)

然后对于询问操作,直接给\(s[y]\)

对于改边的操作

每一次加边,都会在生成树上面添加一个环,然后我们找到环上最大边 \(cut\) 就可以

(\(split\)已经通链了,所以直接断就可以)

然后\(link\)就行了

\[Q.E.D
\]

Code

不是很难写吧

#include <bits/stdc++.h>
using namespace std;
#define int long long
namespace yspm {
inline int read() {
int res = 0, f = 1;
char k;
while (!isdigit(k = getchar()))
if (k == '-')
f = -1;
while (isdigit(k)) res = res * 10 + k - '0', k = getchar();
return res * f;
}
const int M = 1e6 + 10, N = 1e5 + 10;
int f[N], c[N][2], s[N], v[N], st[N], n, m, q, x[N], y[N], opt[N], fa[N], ans[N], id[2010][2010];
bool r[N];
struct node {
int from, to, dis, vis;
bool operator<(const node &a) const { return dis < a.dis; }
} e[M];
inline void push_up(int x) {
s[x] = max(s[c[x][0]], max(s[c[x][1]], v[x]));
return;
}
inline bool notroot(int x) { return c[f[x]][1] == x || c[f[x]][0] == x; }
inline void pushr(int x) {
swap(c[x][0], c[x][1]);
r[x] ^= 1;
return;
}
inline void push_down(int x) {
if (r[x]) {
if (c[x][0])
pushr(c[x][0]);
if (c[x][1])
pushr(c[x][1]);
}
return r[x] = 0, void();
}
inline void rotate(int tx) {
int ty = f[tx], z = f[ty], k = (c[ty][1] == tx), w = c[tx][!k];
if (notroot(ty))
c[z][c[z][1] == ty] = tx;
c[tx][!k] = ty;
c[ty][k] = w;
if (w)
f[w] = ty;
f[ty] = tx;
f[tx] = z;
return push_up(ty), push_up(tx);
}
inline void splay(int x) {
int y = x, z = 0;
st[++z] = y;
while (notroot(y)) st[++z] = y = f[y];
while (z) push_down(st[z--]);
while (notroot(x)) {
y = f[x], z = f[y];
if (notroot(y))
rotate((c[y][0] == x) ^ (c[z][0] == y) ? x : y);
rotate(x);
}
return push_up(y);
}
inline void access(int x) {
for (int y = 0; x; x = f[y = x]) splay(x), c[x][1] = y, push_up(x);
return;
}
inline void makeroot(int x) {
access(x);
splay(x);
pushr(x);
return;
}
inline int findroot(int x) {
access(x);
splay(x);
while (c[x][0]) push_down(x), x = c[x][0];
splay(x);
return x;
}
inline void split(int x, int y) {
makeroot(x);
access(y);
splay(y);
return;
}
inline void link(int x, int y) {
makeroot(x);
if (findroot(y) != x)
f[x] = y;
return;
}
inline void cut(int x, int y) {
makeroot(x);
if (findroot(y) == x && f[y] == x && !c[y][0])
f[y] = c[x][1] = 0, push_up(x);
return;
} inline int find(int x, int val) {
if (v[x] == val)
return x;
return s[c[x][0]] == val ? find(c[x][0], val) : find(c[x][1], val);
} inline int getf(int x) { return x == fa[x] ? x : fa[x] = getf(fa[x]); }
inline void merge(int x, int y) { fa[getf(x)] = getf(y); }
inline void Kruskal() {
for (int i = 1; i <= n; ++i) fa[i] = i;
for (int i = 1; i <= m; ++i) {
if (!e[i].vis && getf(e[i].from) != getf(e[i].to)) {
merge(e[i].from, e[i].to);
link(e[i].from, n + i);
link(e[i].to, n + i);
}
}
return;
} signed main() {
n = read();
m = read();
q = read();
for (int i = 1; i <= m; ++i) e[i].from = read(), e[i].to = read(), e[i].dis = read();
sort(e + 1, e + m + 1);
for (int i = 1; i <= m; ++i) {
id[e[i].from][e[i].to] = id[e[i].to][e[i].from] = i;
v[n + i] = e[i].dis;
}
for (int i = 1; i <= q; ++i) {
opt[i] = read();
x[i] = read();
y[i] = read();
if (opt[i] == 2)
e[id[x[i]][y[i]]].vis = 1;
}
Kruskal();
int num = 0;
for (int i = q; i >= 1; --i) {
split(x[i], y[i]);
if (opt[i] == 1)
ans[++num] = s[y[i]];
else {
int tmp = find(y[i], s[y[i]]);
if (v[id[x[i]][y[i]] + n] < s[y[i]]) {
cut(e[tmp - n].from, tmp);
cut(e[tmp - n].to, tmp);
link(x[i], id[x[i]][y[i]] + n);
link(y[i], id[x[i]][y[i]] + n);
}
}
}
for (int i = num; i >= 1; --i) printf("%lld\n", ans[i]);
return 0;
}
} // namespace yspm
signed main() { return yspm::main(); }

LGOJ4172 WC2006水管局长的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. BZOJ_2594_[Wc2006]水管局长数据加强版_LCT

    BZOJ_2594_[Wc2006]水管局长数据加强版_LCT Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供 ...

  7. P4172 [WC2006]水管局长(LCT)

    P4172 [WC2006]水管局长 LCT维护最小生成树,边权化点权.类似 P2387 [NOI2014]魔法森林(LCT) 离线存储询问,倒序处理,删边改加边. #include<iostr ...

  8. P4172 [WC2006]水管局长

    P4172 [WC2006]水管局长 前言 luogu数据太小 去bzoj,他的数据大一些 思路 正着删不好维护 那就倒着加,没了 LCT维护他的最小生成树MST 树上加一条边肯定会有一个环 看看环上 ...

  9. [BZOJ2594][WC2006]水管局长加强版(LCT+Kruskal)

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

随机推荐

  1. linux系统pid的最大值研究

    内核源码探查 通过对linux内核源码的追踪,可以看到对pid最大值的限定最终集中到include/linux/threads.h文件中的PID_MAX_DEFAULT上了,代码如下: /* * Th ...

  2. text字体样式(多行结尾省略,彩色渐变字体)

    text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; ...

  3. Linux每日一练20200220

  4. UVA - 1615 Highway(高速公路)(贪心+区间选点)

    题意:给定平面上n(n<=105)个点和一个值D,要求在x轴上选出尽量少的点,使得对于给定的每个点,都有一个选出的点离它的欧几里德距离不超过D. 分析: 1.根据D可以算出每个点在x轴上的可选区 ...

  5. zabbix_agent_win

    http://mayulin.blog.51cto.com/1628315/514447/ http://www.cnblogs.com/likehua/p/3968689.html 先下载win客户 ...

  6. comparable接口 和 comparator接口的特点与区别

    1. Comparator 和 Comparable 相同的地方 他们都是java的一个接口, 并且是用来对自定义的class比较大小的. 什么是自定义class: 如 public class Pe ...

  7. URAL_1018 Binary Apple Tree 树形DP+背包

    这个题目给定一棵树,以及树的每个树枝的苹果数量,要求在保留K个树枝的情况下最多能保留多少个苹果 一看就觉得是个树形DP,然后想出 dp[i][j]来表示第i个节点保留j个树枝的最大苹果数,但是在树形过 ...

  8. scanf与gets

    gets函数为什么不能读取字符就往下运行了 这里有一个共性的问题,就是 scanf 输入后,会遗留一个回车符,传递到下面的输入语句: 回车符就会被下面的输入语句接收,而结束了输入,这里就是一个错误的值 ...

  9. 第一章:MySQL架构和历史

    1.MySQL逻辑架构 MySQL存储引擎架构:将查询处理以及其他任务系统和数据的存储处理分离开来,这样做的好处在于可以根据需要灵活选择存储引擎. 第一层架构 -- 连接处理.授权认证.安全等. 第二 ...

  10. POJ - 1127 Jack Straws(几何)

    题意:桌子上放着n根木棍,已知木棍两端的坐标.给定几对木棍,判断每对木棍是否相连.当两根木棍之间有公共点或可以通过相连的木棍间接的连在一起,则认为是相连的. 分析: 1.若线段i与j平行,且有部分重合 ...