[BZOJ2594] [Wc2006]水管局长数据加强版(LCT + kruskal + 离线)
WC这个题真是丧心病狂啊,就是想学习一下怎么处理边权,给我来了这么一个破题!
ORZ hzwer 临摹黄学长代码233 但还是复杂的一匹
理一下思路吧
题目大意:给定一个无向图,多次删除图中的某一条边,求两点间路径最大值的最小值
求两点间的路径最大值的最小值的话,可以求最小生成树,那么这个值就是最小生成树上两点间路径上的最大值
但是题目要求是删除边,LCT维护最小生成树不支持删边操作,那么就离线处理,倒着加边,用LCT维护。
就是这个离线处理是最恶心的。
来说说如何处理边权,把边也抽象成点,那么这个点就和原来边所连的两个点相连,其中边抽象成的点点权为边权,所连接的两个点点权为 0
给边从小到大排序,那么边所抽象成的点的序号即为 边的序号 + n (n 为原来点的个数)
然后再将边按照它所连的两个点为关键字排序,二分查找确定所删除的边的序号。
再按照从小到大的顺序再排回来,跑 kruskal,依次添加没有被删除的边
最后从后往前处理询问,添加一条边的时候先判断两端点是否连通(当然此题不必,因为题目中说:任何时候我们考虑的水管网络都是连通的,即从任一结点A必有至少一条水管路径通往任一结点B。。所以肯定连通)
然后找出两点间路径边权的最大的,判断最大的边权是否大于要加入的边的边权,如果大于,就删除这条边,连接新边,否则就不加入(维护最小生成树)
具体细节看代码
——代码
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 1500005
#define get(x) (son[f[x]][1] == (x))
#define swap(x, y) ((x) ^= (y) ^= (x) ^= (y))
#define isroot(x) (son[f[x]][0] ^ (x) && son[f[x]][1] ^ (x)) int n, m, Q, tot;
int mx[N], rev[N], fa[N], f[N], val[N], son[N][], s[N]; struct node
{
int x, y, z, id;
bool d;
}e[N]; struct ask
{
int f, x, y, ans, id;
}q[N]; inline int read()
{
int x = , f = ;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -;
for(; isdigit(ch); ch = getchar()) x = (x << ) + (x << ) + ch - '';
return x * f;
} inline bool cmp1(node x, node y)
{
return x.z < y.z;
} inline bool cmp2(node x, node y)
{
return x.x < y.x || (x.x == y.x && x.y < y.y);
} inline bool cmp3(node x, node y)
{
return x.id < y.id;
} inline int getf(int x)
{
return x == fa[x] ? x : fa[x] = getf(fa[x]);
} inline int find(int x, int y)
{
int l = , r = m, mid;
while(l <= r)
{
mid = (l + r) >> ;
if(e[mid].x < x || (e[mid].x == x && e[mid].y < y)) l = mid + ;
else if(e[mid].x == x && e[mid].y == y) return mid;
else r = mid - ;
}
} inline void update(int x)
{
if(x)
{
mx[x] = x;
if(son[x][] && val[mx[son[x][]]] > val[mx[x]]) mx[x] = mx[son[x][]];
if(son[x][] && val[mx[son[x][]]] > val[mx[x]]) mx[x] = mx[son[x][]];
}
} inline void pushdown(int x)
{
if(x && rev[x])
{
swap(son[x][], son[x][]);
if(son[x][]) rev[son[x][]] ^= ;
if(son[x][]) rev[son[x][]] ^= ;
rev[x] = ;
}
} inline void rotate(int x)
{
int old = f[x], oldf = f[old], wh = get(x); if(!isroot(old))
son[oldf][get(old)] = x;
f[x] = oldf; son[old][wh] = son[x][wh ^ ];
f[son[old][wh]] = old; son[x][wh ^ ] = old;
f[old] = x; update(old);
update(x);
} inline void splay(int x)
{
int i, fat, t = ;
s[++t] = x;
for(i = x; !isroot(i); i = f[i]) s[++t] = f[i];
for(i = t; i; i--) pushdown(s[i]);
for(; !isroot(x); rotate(x))
if(!isroot(fat = f[x]))
rotate(get(x) ^ get(fat) ? x : fat);
} inline void access(int x)
{
for(int t = ; x; t = x, x = f[x]) splay(x), son[x][] = t, update(x);
} inline void reverse(int x)
{
access(x);
splay(x);
rev[x] ^= ;
} inline void cut(int x, int y)
{
reverse(x);
access(y);
splay(y);
son[y][] = f[x] = ;
update(y);
} inline void link(int x, int y)
{
reverse(x);
f[x] = y;
access(x);
} inline int query(int x, int y)
{
reverse(x);
access(y);
splay(y);
return mx[y];
} int main()
{
int i, j, k, t, x, y, fx, fy;
n = read();
m = read();
Q = read();
for(i = ; i <= n; i++) fa[i] = i;
for(i = ; i <= m; i++)
{
e[i].x = read();
e[i].y = read();
e[i].z = read();
if(e[i].x > e[i].y) swap(e[i].x, e[i].y);
}
std::sort(e + , e + m + , cmp1);
for(i = ; i <= m; i++)
{
e[i].id = i;
val[n + i] = e[i].z;
mx[n + i] = n + i;
}
std::sort(e + , e + m + , cmp2);
for(i = ; i <= Q; i++)
{
q[i].f = read();
q[i].x = read();
q[i].y = read();
if(q[i].x > q[i].y) swap(q[i].x, q[i].y);
if(q[i].f == )
{
t = find(q[i].x, q[i].y);
e[t].d = ;
q[i].id = e[t].id;
}
}
std::sort(e + , e + m + , cmp3);
for(i = ; i <= m; i++)
if(!e[i].d)
{
x = e[i].x;
y = e[i].y;
fx = getf(x);
fy = getf(y);
if(fx ^ fy)
{
fa[fx] = fy;
link(x, i + n);
link(y, i + n);
tot++;
if(tot == n - ) break;
}
}
for(i = Q; i; i--)
{
if(q[i].f == ) q[i].ans = val[query(q[i].x, q[i].y)];
else
{
x = q[i].x;
y = q[i].y;
k = q[i].id;
t = query(x, y);
if(e[k].z < val[t])
{
cut(e[t - n].x, t);
cut(e[t - n].y, t);
link(x, k + n);
link(y, k + n);
}
}
}
for(i = ; i <= Q; i++)
if(q[i].f == )
printf("%d\n", q[i].ans);
return ;
}
[BZOJ2594] [Wc2006]水管局长数据加强版(LCT + kruskal + 离线)的更多相关文章
- BZOJ2594 [Wc2006]水管局长数据加强版 LCT kruskal
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2594 题意概括 N个点的图,M条带权边.(N<=100000,M<=1000000) ...
- [bzoj2594][Wc2006]水管局长数据加强版 (lct)
论蒟蒻的自我修养T_T.. 和noi2014魔法森林基本一样...然而数据范围大得sxbk...UPD:这题如果用lct判联通的话可能会被卡到O(mlogm)..所以最好还是用并查集吧 一开始数组开太 ...
- BZOJ 2594: [Wc2006]水管局长数据加强版 [LCT kruskal]
2594: [Wc2006]水管局长数据加强版 Time Limit: 25 Sec Memory Limit: 128 MBSubmit: 2917 Solved: 918[Submit][St ...
- [bzoj2594][Wc2006]水管局长数据加强版——lct+离线
Brief Description 您有一个无向带权图,您需要支持两种操作. 询问两个点之间的最大权最小路径. 删除一条边. Algorithm Design 我们首先提出一个猜想:最优路径一定在原图 ...
- bzoj2594 [Wc2006]水管局长数据加强版——LCT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2594 时间倒序一下,就是 魔法森林 那道题: 有个不解的地方,是 access 里面关于 p ...
- BZOJ2594: [Wc2006]水管局长数据加强版
题解: 裸LCT+离线+二分+MST... 代码:(几乎摘抄自hzwer) #include<cstdio> #include<cstdlib> #include<cma ...
- BZOJ 2594: [Wc2006]水管局长数据加强版( LCT )
离线然后就是维护加边的动态MST, Link cut tree秒掉..不过我写+调了好久...时间复杂度O(NlogN + MlogM) ------------------------------- ...
- BZOJ2594 [Wc2006]水管局长数据加强版 【LCT维护最小生成树】
题目 SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一条从A至B的水管的 ...
- BZOJ 2594: [Wc2006]水管局长数据加强版(kruskal + LCT)
Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一 ...
随机推荐
- bzoj 1492: [NOI2007]货币兑换Cash【贪心+斜率优化dp+cdq】
参考:http://www.cnblogs.com/lidaxin/p/5240220.html 虽然splay会方便很多,但是懒得写,于是写了cdq 首先要想到贪心的思路,因为如果在某天买入是能得到 ...
- 1642: [Usaco2007 Nov]Milking Time 挤奶时间(dp)
1642: [Usaco2007 Nov]Milking Time 挤奶时间 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 935 Solved: 55 ...
- [App Store Connect帮助]四、添加 App 图标、App 预览和屏幕快照(3)上传 App 预览和屏幕快照
请上传至多三个 App 预览和至多十张屏幕快照.如果您的 App 在不同设备尺寸和本地化内容间都相同,仅提供所要求的最高分辨率的屏幕快照即可. 对于 iPhone,必须提供用于 5.5 英寸设备(iP ...
- Linux之线程相关命令及常用命令
查进程 top命令:查看系统的资源状况.#top top -d 10 //指定系统更新进程的时间为10秒 ps:查看当前用户的活动进程.#ps -A ps命令查找与进程相关的PID号: ps ...
- N - Binomial Showdown (组合数学)
Description In how many ways can you choose k elements out of n elements, not taking order into acco ...
- RHEL5.6更新yum源
RHEL5.6更新yum源记录,2017年2月20日 root用户切换目录至:/etc/yum.repos.d/ [root@localhost yum.repos.d]# pwd /etc/yum. ...
- C#基础 进制转换6/17
二进制→十进制: 计算公式:a*20+b*21+c*22+…+m*2(n-1) 公式中a为二进制数右边第一位数,b为第二位数,以此类推 例:二进制1011010转换为十进制数为 0*20+1*21+0 ...
- HTML+CSS 基础布局(案列一)
刚html刚讲完马上就接着css,周末的任务就是高仿案例,结果有点遭 图文布局 代码 css(内部样式) html <!DOCTYPE html><html><head& ...
- sql删除表中重复记录只保留一条记录
最终代码 update T_Fee set gzl_dfg_op = 'delete' where MetReadRecordID in ( select MetReadRecordID from T ...
- hihocoder1365 图片排版
思路: 模拟,枚举,dp. 参考了https://github.com/buptlxb/hihoCoder/blob/master/solutions/1365/picture_arrange.cpp ...