【CF603E】Pastoral Oddities cdq分治+并查集
【CF603E】Pastoral Oddities
题意:有n个点,依次加入m条边权为$l_i$的无向边,每次加入后询问:当前图是否存在一个生成子图,满足所有点的度数都是奇数。如果有,输出这个生成子图中边权最大的边的权值最小可能是多少。
$n\le 10^5,m\le 10^6,l_i\le 10^9$
题解:可以证明如果存在一个生成子图满足所有点度数都是奇数,当且仅当所有连通块都有偶数个点。并且可以知道加边一定不会使答案更劣。正解有三种:1.LCT维护最小生成树;2.cdq分治(类似整体二分);3.线段树(类似按时间分治)。都比较神,本人采用了第二种。
官方题解:http://codeforces.com/blog/entry/21914
大神的第二种做法的题解:https://www.cnblogs.com/galaxies/p/cf603E.html
- #include <cstdio>
- #include <cstring>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- const int maxn=100010;
- const int maxm=300010;
- int f[maxn],g[maxn],siz[maxn],st[maxn],ans[maxm];
- int n,m,cnt,top;
- struct edge
- {
- int a,b,c,tim;
- }p[maxm],q[maxm];
- bool cmp(const edge &a,const edge &b)
- {
- return (a.c==b.c)?(a.tim<b.tim):(a.c<b.c);
- }
- inline void uni(int a,int b)
- {
- int x=a,y=b,c=0,d=0;
- while(f[x]!=x) x=f[x],c++;
- while(f[y]!=y) y=f[y],d++;
- if(x==y) return ;
- if(c>d) swap(x,y),swap(a,b);
- cnt-=(siz[x]&1)+(siz[y]&1)-((siz[x]+siz[y])&1);
- siz[y]+=siz[x],f[x]=y;
- st[++top]=x;
- }
- inline void del(int x)
- {
- int y=f[x];
- siz[y]-=siz[x],f[x]=x;
- cnt+=(siz[x]&1)+(siz[y]&1)-((siz[x]+siz[y])&1);
- }
- void solve(int l,int r,int L,int R)
- {
- if(l>r) return ;
- int mid=(l+r)>>1,i,now=top,MID;
- for(i=l;i<=mid;i++) if(p[i].c<=L) uni(p[i].a,p[i].b);
- for(i=L;i<=R&&cnt;i++) if(q[i].tim<=mid) uni(q[i].a,q[i].b);
- MID=max(L,i-1);
- if(!cnt) ans[p[mid].tim]=q[MID].c;
- else ans[p[mid].tim]=-1;
- while(top>now) del(st[top--]);
- for(i=L;i<=MID;i++) if(q[i].tim<=l) uni(q[i].a,q[i].b);
- solve(l,mid-1,MID,R);
- while(top>now) del(st[top--]);
- for(i=l;i<=mid;i++) if(p[i].c<=L) uni(p[i].a,p[i].b);
- solve(mid+1,r,L,MID);
- while(top>now) del(st[top--]);
- }
- inline int rd()
- {
- int ret=0,f=1; char gc=getchar();
- while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
- while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
- return ret*f;
- }
- int main()
- {
- n=rd(),m=rd();
- int i;
- for(i=1;i<=m;i++) p[i].a=rd(),p[i].b=rd(),p[i].c=rd(),p[i].tim=i,q[i]=p[i];
- sort(q+1,q+m+1,cmp);
- for(i=1;i<=n;i++) f[i]=i,siz[i]=1;
- for(i=1;i<=m;i++) p[q[i].tim].c=i;
- cnt=n;
- solve(1,m,1,m);
- for(i=1;i<=m;i++) printf("%d\n",ans[i]);
- return 0;
- }
【CF603E】Pastoral Oddities cdq分治+并查集的更多相关文章
- 【openjudge】C15C Rabbit's Festival CDQ分治+并查集
题目链接:http://poj.openjudge.cn/practice/C15C/ 题意:n 点 m 边 k 天.每条边在某一天会消失(仅仅那一天消失).问每一天有多少对点可以相互到达. 解法:开 ...
- hdu_5354_Bipartite Graph(cdq分治+并查集判二分图)
题目链接:hdu_5354_Bipartite Graph 题意: 给你一个由无向边连接的图,问对于每一个点来说,如果删除这个点,剩下的点能不能构成一个二分图. 题解: 如果每次排除一个点然后去DFS ...
- BZOJ 4025: 二分图 [线段树CDQ分治 并查集]
4025: 二分图 题意:加入边,删除边,查询当前图是否为二分图 本来想练lct,然后发现了线段树分治的做法,感觉好厉害. lct做法的核心就是维护删除时间的最大生成树 首先口胡一个分块做法,和hno ...
- 2018.10.01 bzoj3237: [Ahoi2013]连通图(cdq分治+并查集)
传送门 cdq分治好题. 对于一条边,如果加上它刚好连通的话,那么删掉它会有两个大集合A,B.于是我们先将B中禁用的边连上,把A中禁用的边禁用,再递归处理A:然后把A中禁用的边连上,把B中禁用的边禁用 ...
- [HDU5354]Bipartite Graph(CDQ分治+并查集)
经典动态二分图问题. 考虑solve(l,r)分治成l,mid和mid+1,r.先将区间[mid+1,r]中的点全部加入图中,若此时存在奇环则ans[l..mid]全部为0,否则递归到左边. 递归完左 ...
- CF603E Pastoral Oddities
CF603E Pastoral Oddities 度数不好处理.转化题意:不存在连通块为奇数时候就成功了(自底向上调整法证明) 暴力:从小到大排序加入.并查集维护.全局变量记录奇数连通块的个数 答案单 ...
- 2018.09.30 bzoj4025: 二分图(线段树分治+并查集)
传送门 线段树分治好题. 这道题实际上有很多不同的做法: cdq分治. lct. - 而我学习了dzyo的线段树分治+并查集写法. 所谓线段树分治就是先把操作分成lognlognlogn个连续不相交的 ...
- 2015多校第6场 HDU 5354 Bipartite Graph CDQ,并查集
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5354 题意:求删去每个点后图是否存在奇环(n,m<=1e5) 解法:很经典的套路,和这题一样:h ...
- 【CF576E】Painting Edges 线段树按时间分治+并查集
[CF576E]Painting Edges 题意:给你一张n个点,m条边的无向图,每条边是k种颜色中的一种,满足所有颜色相同的边内部形成一个二分图.有q个询问,每次询问给出a,b代表将编号为a的边染 ...
随机推荐
- ABBYY FineReader 14助力2017,正式进入新纪元
ABBYY FineReader 12自2014年推出以来,已经给万千用户的工作带来了便捷,蝉联优秀殊荣这么久,相信不少用户早在期待新版本的到来了吧.这不,ABBYY FineReader 14问世了 ...
- QT编译错误: multiple definition of `qMain(int, char**)'
QT使用过程中来回添加修改代码,结果出现了编译错误:error: multiple definition of `qMain(int, char**)' 一直看我的源文件是都哪里有错误,最后发现是在p ...
- 更改mysql的加密方式和密码策略
-- 修改密码为用不过期 mysql> ALTER USER 'root'@'%' IDENTIFIED BY 'password' PASSWORD EXPIRE NEVER; Query O ...
- 变分推断(Variational Inference)
(学习这部分内容大约需要花费1.1小时) 摘要 在我们感兴趣的大多数概率模型中, 计算后验边际或准确计算归一化常数都是很困难的. 变分推断(variational inference)是一个近似计算这 ...
- mongodb 初学 索引
连接服务器异常(Connection refused) 啦啦啦 mongodb 搭建主从服务器 啦啦啦 Mongodb启动命令mongod参数说明 啦啦啦 MongoDB 分片 啦啦啦 啦啦啦 啦啦啦 ...
- Linux 集群架构
集群介绍 Keepalived 配置高可用集群
- Splash Lua 脚本
Splash 可以通过 Lua 脚本执行一系列渲染操作,这样我们就可以用 Splash 来模拟浏览器的操作了,Splash Lua 基础语法如下: function main(splash, args ...
- Ansible的快速入门
Ansible 是一个简单的自动化引擎,可完成配置管理,应用部署,服务编排等各种IT需求. Ansible使用python语言开发实现的开源软件,依赖于Jinjia2,paramiko和PyYAML这 ...
- [Ubuntu] APT - Advanced Packaging Tool 简明指南
Advanced Packaging Tool,一般简称为apt,是Debian GNU/Linux distribution及其变体版本中与核心库一道处理软件的安装和卸载. Ubuntu是Debia ...
- 重写MFC窗口上的关闭按钮事件(SDI, MDI, Dialog)
This piece of code demonstrate how to override WM_CLOSE event. 点击窗口关闭按钮,触发相关事件! 有时候,在MFC程序退出之前,我们通常会 ...