hdu 5333 Undirected Graph (LCT)
来源:互联网 发布:windows vista界面 编辑:程序博客网 时间:2024/05/22 00:42
题意:
n个点和m条边的无向图,q个询问,每次询问[L,R],问删去至少有一个端点不在[L,R]内的边,剩下的图构成多少个联通分量。
思路:
高中生出的题。。能离线绝逼要离线搞。。否则有在线的搞法的话就一定会强制在线。。
询问按照R排序,边按照端点较大的排序,从小到大来扫询问,比如,扫到Ri时,将较大端点小于等于Ri的边以较小端点为权值加入图中,如果形成环的话,就要删去环上最小的边,也就是维护图的最大生成森林,因为对于询问[L,R],如果权值较大的边都小于L的话,那么权值更小的边也是不考虑的,用LCT维护最大生成森林,tot记录森林中的总边数,树状数组记录边权个数,答案就是n-(tot-t),t是生成森林中小于L的边的个数。
#include<iostream>#include<string>#include<cstring>#include<cstdio>#include<cmath>#include<queue>#include<set>#include<algorithm>using namespace std;#define LL long long#define eps 1e-8#define MP make_pair#define N 500020#define M 80020#pragma comment(linker, "/STACK:1024000000,1024000000")#define ls (i << 1)#define rs (ls | 1)#define md ((ll + rr) >> 1)#define lson ll, md, ls#define rson md + 1, rr, rs#define mod 258280327#define inf 0x3f3f3f3f#define ULL unsigned long longint readint() { char c; while((c = getchar()) && !(c >= '0' && c <= '9')); int ret = c - '0'; while((c = getchar()) && c >= '0' && c <= '9') ret = ret * 10 + c - '0'; return ret;}struct edge { int u, v; edge() {} void input() { u = readint(); v = readint(); if(u < v) swap(u, v); } bool operator < (const edge &b) const { return u < b.u; }}a[N];struct query { int l, r, ans, id; void input(int id) { this -> id = id; l = readint(); r = readint(); ans = 0; } bool operator < (const query &b) const { return r < b.r; }}b[N];int ch[N][2], rt[N], pre[N], rev[N], mi[N];int val[N];int key[N];int n, m, q;int bit[N];void update_rev(int x) { if(!x) return; rev[x] ^= 1; swap(ch[x][0], ch[x][1]);}bool judge(int x, int y) { while(pre[x]) x = pre[x]; while(pre[y]) y = pre[y]; return x == y;}void push_up(int x) { mi[x] = key[x]; if(val[mi[ch[x][0]]] < val[mi[x]]) mi[x] = mi[ch[x][0]]; if(val[mi[ch[x][1]]] < val[mi[x]]) mi[x] = mi[ch[x][1]];}void push_down(int x) { if(rev[x]) { update_rev(ch[x][0]); update_rev(ch[x][1]); rev[x] = 0; }}void P(int x) { if(!rt[x]) P(pre[x]); push_down(x);}void rot(int x) { int y = pre[x], d = ch[y][1] == x; ch[y][d] = ch[x][!d]; pre[ch[x][!d]] = y; pre[x] = pre[y]; pre[y] = x; ch[x][!d] = y; if(rt[y]) rt[y] = false, rt[x] = true; else ch[pre[x]][ch[pre[x]][1]==y] = x; push_up(y);}void splay(int x) { P(x); while(!rt[x]) { int f = pre[x], ff = pre[f]; if(rt[f]) rot(x); else if((ch[ff][1] == f) == (ch[f][1] == x)) rot(f), rot(x); else rot(x), rot(x); } push_up(x);}void Access(int x) { int y = 0; for(; x; y = x, x = pre[x]) { splay(x); rt[ch[x][1]] = true; ch[x][1] = y; rt[y] = false; push_up(x); }}void make_root(int x) { Access(x); splay(x); update_rev(x);}void link(int x, int y) { make_root(x); pre[x] = y;}void cut(int x, int y) { make_root(x); splay(y); pre[ch[y][0]] = pre[y]; pre[y] = 0; rt[ch[y][0]] = true; ch[y][0] = 0; push_up(y);}void lca(int &x, int &y) { Access(y), y = 0; for(splay(x); pre[x]; y = x, x = pre[x], splay(x)) { rt[ch[x][1]] = true; ch[x][1] = y; rt[y] = false; push_up(x); }}//okint query_mi(int x, int y) { /* make_root(x); Access(y); splay(y); return mi[y]; */ lca(x, y); int ret = key[x]; if(val[mi[y]] < val[ret]) ret = mi[y]; if(val[mi[ch[x][1]]] < val[ret]) ret = mi[ch[x][1]]; return ret;}bool cmp(query x, query y) { return x.id < y.id;}//okvoid bit_add(int x, int v) { // printf("bit_add %d %d\n", x, v); while(x <= n) { bit[x] += v; x += x & -x; }}//okint bit_query(int x) { int ret = 0; while(x) { ret += bit[x]; x -= x & -x; } return ret;}int main() { //freopen("tt.txt", "r", stdin); while(scanf("%d%d%d", &n, &m, &q) != EOF) { for(int i = 1; i <= m; ++i) { a[i].input(); } for(int i = 1; i <= q; ++i) { b[i].input(i); } sort(a + 1, a + m + 1); sort(b + 1, b + q + 1); for(int i = 0; i <= n; ++i) val[i] = inf; for(int i = 1; i <= m; ++i) val[i+n] = a[i].v; int j = 1; for(int i = 1; i <= n + m; ++i) { pre[i] = 0; rt[i] = 1; key[i] = i; mi[i] = i; ch[i][0] = ch[i][1] = 0; rev[i] = 0; } for(int i = 1; i <= n; ++i) bit[i] = 0; int tot = 0; for(int i = 1; i <= q; ++i) { while(j <= m && a[j].u <= b[i].r) { int u = a[j].u, v = a[j].v; if(!judge(u, v)) { link(u, j + n); link(v, j + n); bit_add(val[j+n], 1); ++tot; } else { int t = query_mi(u, v); if(val[t] < val[j+n]) { cut(a[t-n].u, t); cut(a[t-n].v, t); bit_add(val[t], -1); link(u, j + n); link(v, j + n); bit_add(val[j+n], 1); } } ++j; } int t = bit_query(b[i].l - 1); b[i].ans = n - (tot - t); } sort(b + 1, b + q + 1, cmp); for(int i = 1; i <= q; ++i) printf("%d\n", b[i].ans); } return 0;}
0 0
- hdu 5333 Undirected Graph (LCT)
- 【HDU】5333 Undirected Graph【LCT+BIT】
- HDU 5333 Undirected Graph LCT+BIT
- HDU 5333 Undirected Graph【LCT+BIT】
- [LCT 树状数组] HDU 5333 Undirected Graph
- HDU 5333 Undirected Graph
- HDU 5333 Undirected Graph 离线 LCT维护最大生成树+树状数组
- 【动态树】 HDOJ 5333 Undirected Graph
- HDU5333 Undirected Graph
- Undirected Graph BFS/DFS
- judge loop in undirected graph
- connect components in undirected graph
- Connected Component in Undirected Graph
- HDU 5333 [LCT][树状数组]
- implement a undirected graph use adjacent list
- Sicily 4378. connect components in undirected graph
- Detect cycle in an undirected graph
- Sicily 1002. connected components in undirected graph
- HTML生成一个二维码,微信扫一扫,可以对网页分享
- inDensity,inTargetDensity,inScreenDensity关系详解
- nutch 过滤字符
- PAT (Advanced Level) 1099. Build A Binary Search Tree (30) 中序遍历往BST中填数据
- 有符号char的+、-法位运算过程
- hdu 5333 Undirected Graph (LCT)
- qt学习第二课:建立链接
- HDU 4983/BC 6C Goffi and GCD
- ASP.NET MsChart 控件出错:为 ChartImg.axd 执行子请求时出错
- android的内容提供者
- CNN卷积神经网络推导和实现
- 从NSDictionary 取出int型的数据
- 二叉树的前序遍历三种方法
- Spring 循环引用 ——理解singleton与prototype初始化的区别