[BZOJ2594] [Wc2006]水管局长数据加强版(LCT + kruskal + 离线)
2017-06-17 18:43
501 查看
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 , rev , fa , f , val , son [2], s ; struct node { int x, y, z, id; bool d; }e ; struct ask { int f, x, y, ans, id; }q ; inline int read() { int x = 0, f = 1; char ch = getchar(); for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1; for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0'; 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 = 1, r = m, mid; while(l <= r) { mid = (l + r) >> 1; if(e[mid].x < x || (e[mid].x == x && e[mid].y < y)) l = mid + 1; else if(e[mid].x == x && e[mid].y == y) return mid; else r = mid - 1; } } inline void update(int x) { if(x) { mx[x] = x; if(son[x][0] && val[mx[son[x][0]]] > val[mx[x]]) mx[x] = mx[son[x][0]]; if(son[x][1] && val[mx[son[x][1]]] > val[mx[x]]) mx[x] = mx[son[x][1]]; } } inline void pushdown(int x) { if(x && rev[x]) { swap(son[x][0], son[x][1]); if(son[x][0]) rev[son[x][0]] ^= 1; if(son[x][1]) rev[son[x][1]] ^= 1; rev[x] = 0; } } 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 ^ 1]; f[son[old][wh]] = old; son[x][wh ^ 1] = old; f[old] = x; update(old); update(x); } inline void splay(int x) { int i, fat, t = 0; 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 = 0; x; t = x, x = f[x]) splay(x), son[x][1] = t, update(x); } inline void reverse(int x) { access(x); splay(x); rev[x] ^= 1; } inline void cut(int x, int y) { reverse(x); access(y); splay(y); son[y][0] = f[x] = 0; 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 = 1; i <= n; i++) fa[i] = i; for(i = 1; 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 + 1, e + m + 1, cmp1); for(i = 1; i <= m; i++) { e[i].id = i; val[n + i] = e[i].z; mx[n + i] = n + i; } std::sort(e + 1, e + m + 1, cmp2); for(i = 1; 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 == 2) { t = find(q[i].x, q[i].y); e[t].d = 1; q[i].id = e[t].id; } } std::sort(e + 1, e + m + 1, cmp3); for(i = 1; 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 - 1) break; } } for(i = Q; i; i--) { if(q[i].f == 1) 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 = 1; i <= Q; i++) if(q[i].f == 1) printf("%d\n", q[i].ans); return 0; }View Code
相关文章推荐
- BZOJ 2594: [Wc2006]水管局长数据加强版 [LCT kruskal]
- BZOJ 2594: [Wc2006]水管局长数据加强版(LCT+最小生成树+离线)
- [BZOJ2594][Wc2006]水管局长数据加强版(kruskal+lct)
- [bzoj2594][Wc2006]水管局长数据加强版——lct+离线
- BZOJ 2594: [Wc2006]水管局长数据加强版(kruskal + LCT)
- bzoj 2594: [Wc2006]水管局长数据加强版(LCT+最小生成树+离线)
- [动态树 LCT] BZOJ 2594 [Wc2006]水管局长数据加强版
- BZOJ2594 [Wc2006]水管局长数据加强版 【LCT维护最小生成树】
- [BZOJ 2594] [Wc2006]水管局长数据加强版 【LCT】
- [BZOJ2594][WC2006]水管局长数据加强版(LCT维护最小生成树)
- BZOJ 2594 [Wc2006]水管局长数据加强版 LCT
- [bzoj2594][Wc2006]水管局长数据加强版 (lct)
- [BZOJ2594][WC2006][LCT][MST]水管局长数据加强版
- [BZOJ2594][WC2006]水管局长加强版(LCT+Kruskal)
- bzoj 2594 [Wc2006]水管局长数据加强版(LCT+最小生成树)
- BZOJ 2594: [Wc2006]水管局长数据加强版( LCT )
- BZOJ_2594_[Wc2006]水管局长数据加强版_LCT
- [BZOJ2594][Wc2006][LCT]水管局长数据加强版
- BZOJ 2594 【WC2006】 水管局长数据加强版
- 【bzoj2594】[Wc2006]水管局长数据加强版