Link-Cut-Tree题目泛做(为了对应自己的课件)
2016-01-27 20:55
387 查看
题目1:BZOJ 2049 洞穴勘测
HDU 4010
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <iostream> #define L(x) c[x][0] #define R(x) c[x][1] using namespace std; const int N = 300000 + 5; const int oo = 0x3f3f3f3f; int n, m, tot; int first , nxt[N<<1]; int u[N<<1], v[N<<1]; int que[N<<1]; struct SplayTree{ int fa , c [2], val , mx , add ; bool rev ; int top, st ; inline bool isroot(int x){ return L(fa[x]) != x && R(fa[x]) != x; } void pushup(int x){ int l = L(x), r = R(x); mx[x] = max(mx[l], mx[r]); mx[x] = max(mx[x], val[x]); } void pushdown(int x){ int l = L(x), r = R(x); if(rev[x]){ rev[x] ^= 1; rev[l] ^= 1; rev[r] ^= 1; swap(L(x), R(x)); } if(add[x]){ if(l){ add[l] += add[x]; mx[l] += add[x]; val[l] += add[x]; } if(r){ add[r] += add[x]; mx[r] += add[x]; val[r] += add[x]; } add[x] = 0; } } void rotate(int x){ int y = fa[x], z = fa[y], l, r; l = (L(y) == x) ^ 1; r = l ^ 1; if(!isroot(y)){ c[z][L(z) == y ^ 1] = x; } fa[x] = z; fa[y] = x; fa[c[x][r]] = y; c[y][l] = c[x][r]; c[x][r] = y; pushup(y); pushup(x); } void splay(int x){ top = 0; st[++ top] = x; for(int i = x; !isroot(i); i = fa[i]) st[++ top] = fa[i]; while(top) pushdown(st[top --]); while(!isroot(x)){ int y = fa[x], z = fa[y]; if(!isroot(y)){ if(L(y) == x ^ L(z) == y) rotate(x); else rotate(y); } rotate(x); } } }Splay; struct LinkCutTree{ void Access(int x){ int t = 0; while(x){ Splay.splay(x); Splay.R(x) = t; t = x; Splay.pushup(x); x = Splay.fa[x]; } } void Add(int x, int y, int w){ makeroot(x); Access(y); Splay.splay(y); Splay.add[y] += w; Splay.val[y] += w; Splay.mx[y] += w; } int findroot(int x){ Access(x); Splay.splay(x); int y = x; while(Splay.L(y)){ y = Splay.L(y); } return y; } void makeroot(int x){ Access(x); Splay.splay(x); Splay.rev[x] ^= 1; } void cut(int x, int y){ makeroot(x); Access(y); Splay.splay(y); Splay.L(y) = Splay.fa[Splay.L(y)] = 0; Splay.pushup(y); } void link(int x, int y){ makeroot(x); Splay.fa[x] = y; Splay.splay(x); } }lct; void insert(int s, int t){ ++ tot; u[tot] = s; v[tot] = t; nxt[tot] = first[s]; first[s] = tot; } void bfs(){ int head, tail; head = tail = 1; que[head] = 1; Splay.fa[1] = 0; while(head <= tail){ int x = que[head]; for(int i = first[x]; i; i = nxt[i]){ if(v[i] != Splay.fa[x]){ Splay.fa[v[i]] = x; que[++ tail] = v[i]; } } ++ head; } } int main(){ int flag, x, y, z; while(~scanf("%d", &n)){ tot = 0; for(int i = 0; i <= n; ++ i){ Splay.fa[i] = Splay.val[i] = Splay.add[i] = 0; Splay.rev[i] = false; Splay.mx[i] = -oo; Splay.c[i][0] = Splay.c[i][1] = 0; first[i] = 0; } for(int i = 1; i < n; ++ i){ scanf("%d%d", &x, &y); insert(x, y); insert(y, x); } for(int i = 1; i <= n; ++ i){ scanf("%d", &x); Splay.val[i] = Splay.mx[i] = x; } bfs(); scanf("%d", &m); for(int i = 1; i <= m; ++ i){ scanf("%d", &flag); switch(flag){ case 1:{ scanf("%d%d", &x, &y); if(lct.findroot(x) == lct.findroot(y)) puts("-1"); else lct.link(x, y); break; } case 2:{ scanf("%d%d", &x, &y); if(lct.findroot(x) != lct.findroot(y) || x == y) puts("-1"); else lct.cut(x, y); break; } case 3:{ scanf("%d%d%d", &z, &x, &y); if(lct.findroot(x) != lct.findroot(y)) puts("-1"); else lct.Add(x, y, z); break; } case 4:{ scanf("%d%d", &x, &y); if(lct.findroot(x) != lct.findroot(y)) puts("-1"); else{ lct.makeroot(x); lct.Access(y); Splay.splay(y); printf("%d\n", Splay.mx[y]); } break; } } } puts(""); } return 0; }
HDU 4010
相关文章推荐
- 英语数字转换器
- nyoj 1236 挑战密室(河南省第八届acm程序设计大赛)
- ORACLE表空间和表碎片分析及整理方法
- 如何判断一棵二叉树是完全二叉树(1)
- Linux Shell算数运算
- 【BZOJ3282】Tree
- 线性规划问题和MATLAB函数linprog的使用
- iOS实现APP调用打电话,发短信,发邮件,打开Safari
- 数据库锁、隔离级别
- 每天学习十分钟19之git笔记①
- Python for everyone chapter 1
- (译)Real-Time Hair Simulating And Rendering
- CROSS JOIN连接用于生成两张表的笛卡尔集
- 大数模板
- python学习----------socket
- C#之正则表达式
- tab group of firefox
- Nginx根据目录自动生成二级域名
- Geekband 2.2GridView&ListView
- iptables