博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ4025 二分图 线段树分治、带权并查集
阅读量:4574 次
发布时间:2019-06-08

本文共 2438 字,大约阅读时间需要 8 分钟。


如果边不会消失,那么显然可以带权并查集做(然后发现自己不会写带权并查集

但是每条边有消失时间。这样每一条边产生贡献的时间对应一段区间,故对时间轴建立线段树,将每一条边扔到线段树对应的点上。

然后遍历整棵线段树,每遍历到一个点将覆盖这个点对应区间的边全部加入带权并查集中,递归到叶子节点输出答案。回溯的时候把在这一个点加入的边从并查集中栈序撤销。

因为需要撤销所以并查集不能使用路径压缩,只能按秩合并。

#include
#include
#include
#include
//This code is written by Itstusing namespace std;inline int read(){ int a = 0; char c = getchar(); while(!isdigit(c)) c = getchar(); while(isdigit(c)){ a = a * 10 + c - 48; c = getchar(); } return a;}const int MAXN = 1e5 + 7;int N , M , T;#define PII pair < int , int >#define st first#define nd second#define mid ((l + r) >> 1)#define lch (x << 1)#define rch (x << 1 | 1)vector < PII > Edge[MAXN << 2];void addEd(int x , int l , int r , int L , int R , PII Ed){ if(l >= L && r <= R){ Edge[x].push_back(Ed); return; } if(mid >= L) addEd(lch , l , mid , L , R , Ed); if(mid < R) addEd(rch , mid + 1 , r , L , R , Ed);}struct node{ int fa , val , sz;}dsu[MAXN];PII find(int x){ if(dsu[x].fa == x) return PII(x , 0); PII t = find(dsu[x].fa); return PII(t.st , t.nd ^ dsu[x].val);}void solve(int x , int l , int r , bool f){ stack < int > stk; for(vector < PII > :: iterator t = Edge[x].begin() ; t != Edge[x].end() ; ++t){ int p = (*t).st , q = (*t).nd; PII M = find(p) , N = find(q); int m = M.st , n = N.st; if(m != n){ if(dsu[m].sz > dsu[n].sz) swap(n , m); dsu[n].sz += dsu[m].sz; dsu[m].fa = n; dsu[m].val = M.nd ^ N.nd ^ 1; stk.push(m); } else f &= (M.nd ^ N.nd); } if(l == r) puts(f ? "Yes" : "No"); else{ solve(lch , l , mid , f); solve(rch , mid + 1 , r , f); } while(!stk.empty()){ int t = stk.top(); stk.pop(); dsu[dsu[t].fa].sz -= dsu[t].sz; dsu[t].val = 0; dsu[t].fa = t; }}int main(){#ifndef ONLINE_JUDGE freopen("in","r",stdin); freopen("out","w",stdout);#endif N = read(); M = read(); T = read(); for(int i = 1 ; i <= M ; ++i){ int a = read() , b = read() , l = read() , r = read(); if(l < r) addEd(1 , 1 , T , l + 1 , r , PII(a , b)); } for(int i = 1 ; i <= N ; ++i){ dsu[i].fa = i; dsu[i].sz = 1; } solve(1 , 1 , T , 1); return 0;}

转载于:https://www.cnblogs.com/Itst/p/10624143.html

你可能感兴趣的文章
python基础--01安装
查看>>
Spring boot配置mybatis多数据源
查看>>
获取系统的相关文件夹
查看>>
PAT-乙级-1008. 数组元素循环右移问题 (20)
查看>>
OpenCV 传统分割测试
查看>>
Springboot拦截器线上代码失效
查看>>
WCF初探-2:手动实现WCF程序
查看>>
好程序员技术分享html5和JavaScript的区别
查看>>
好程序员web前端分享CSS3文本属性
查看>>
ThinkPHP3.0启动过程
查看>>
Java入门 之 类和对象(一) - 类
查看>>
16级第二周寒假作业E题
查看>>
Java实现Windows锁屏
查看>>
在线会话管理
查看>>
文本处理之可视化wordcloud
查看>>
SampleManager(赛默飞)
查看>>
堆排序
查看>>
我的面试问题记录
查看>>
函数PARSENAME使用和截取字符串
查看>>
关乎性能的判断,请作出果断选择
查看>>