CF19E Fairy(树上差分)
题目描述
很久很久以前,有一个仙女叫做A。有一天一个少年B找到她,并且请求她预测他的未来。仙女看着她的水晶球,说这位少年不久将遇见世界上最美丽的公主,并且将迎娶她为妻。然后仙女在一张纸上画了n个点,并把它们分为几个板块,每个板块以一些点为始,另一些点为终。画完这幅画,仙女要求少年擦掉之上的一个板块。然后她尝试给每个点画上红色或蓝色,让纸上没有板块有和它的结尾颜色一样的点。如果她能做到,这个预言将会成真。B想邂逅世界上最美丽的公主,所以他想要你帮助他。找到所有能帮助他邂逅公主的板块。
输入输出格式:
输入格式:
输入文件的第一行有两个整数:n——点数;m:板块个数。
接下来的m行有板块的描述。每一个描述有两个整数,用空格隔开——v,u——各点的编号(index),由此板块连接。没有板块在描述中会被描述两次。
输出格式:
输出文件的第一行输出数字k——答案中板块的数量。输出文件的第二行输出k个数字,以空格隔开————每个板块的编号,升序排列。每个编号只应被输出一次。板块从1开始编号,以输入的顺序为序。
题解
因为二分图没有奇环,我们就把奇环删掉就行了。
实际上需要分情况讨论:
当没有奇环时,随便删掉一条边即可。
当只有一个奇环时,删掉这个奇环上没有被偶环覆盖的边就行(因为把一个奇环和一个偶环的公共边删去还是一个奇环)
当有多条奇环时,删掉被所有奇环覆盖的且不被偶环覆盖的边。
代码细节很多具体看代码
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=;
int n,m,sum,ans,cnt;
int f[maxn],to[maxn<<],next[maxn<<],book[maxn<<],head[maxn],pa[maxn],pb[maxn],vis[maxn],dep[maxn];
int fa[maxn][],Log[maxn],pc[maxn],s1[maxn],s0[maxn],from[maxn],bok[maxn];
inline void add(int a,int b){
to[++cnt]=b;
next[cnt]=head[a];
head[a]=cnt;
}
void dfs1(int x){
vis[x]=;
for(int i=head[x];i;i=next[i])
if(!vis[to[i]])
book[i]=,fa[to[i]][]=x,dep[to[i]]=dep[x]+,from[to[i]]=(i>>),dfs1(to[i]);
}
int lca(int u,int v){
if(dep[u]<dep[v])swap(u,v);
for(int i=;i>=;i--){
if(dep[fa[u][i]]>=dep[v])u=fa[u][i];
}
if(u==v)return v;
for(int i=;i>=;i--){
if(fa[u][i]!=fa[v][i]){
u=fa[u][i];v=fa[v][i];
}
}
return fa[u][];
}
void dfs2(int x){
for(int i=head[x];i;i=next[i])
if(book[i])
dfs2(to[i]),s1[x]+=s1[to[i]],s0[x]+=s0[to[i]];
}
int main()
{
scanf("%d%d",&n,&m);
cnt=;
int i,j;
for(i=;i<=m;i++){
scanf("%d%d",&pa[i],&pb[i]);add(pa[i],pb[i]);add(pb[i],pa[i]);
}
for(i=;i<=n;i++) if(!vis[i]) dep[i]=,dfs1(i);
for(int i=;i<=;i++)
for(int j=;j<=n;j++){
fa[j][i]=fa[fa[j][i-]][i-];
}
for(i=;i<=m;i++)
if(!book[i*]&&!book[i*+]){
pc[i]=lca(pa[i],pb[i]);
if(!((dep[pa[i]]^dep[pb[i]])&))sum++,s1[pa[i]]++,s1[pb[i]]++,s1[pc[i]]-=;
else s0[pa[i]]++,s0[pb[i]]++,s0[pc[i]]-=;
}
for(i=;i<=n;i++)if(dep[i]==)dfs2(i);
if(!sum){
printf("%d\n",m);
for(i=;i<=m;i++)printf("%d ",i);
return ;
}
if(sum==)
for(i=;i<=m;i++)
if(!book[i*]&&!book[i*+]&&!((dep[pa[i]]^dep[pb[i]])&))bok[i]=,ans++;
for(i=;i<=n;i++)
if(s1[i]==sum&&!s0[i])bok[from[i]]=,ans++;
printf("%d\n",ans);
for(i=;i<=m;i++)
if(bok[i])printf("%d ",i);
return ;
}
CF19E Fairy(树上差分)的更多相关文章
- CF 19E Fairy——树上差分
题目:http://codeforces.com/contest/19/problem/E 去掉一条边,使无向图变成二分图. 该边应该被所有奇环经过,且不被偶环经过. 因为一条非树边一定只在一个环里. ...
- CF19 E Fairy——树上差分
题目:http://codeforces.com/contest/19/problem/E 先把图连成一棵树,然后对于每条非树边,判断它是在奇环中还是偶环中: 把环上的点打上相应的差分标记,并记录有多 ...
- BZOJ4424/CF19E Fairy(dfs树+树上差分)
即删除一条边使图中不存在奇环.如果本身就是个二分图当然任意一条边都可以,先check一下.否则肯定要删除在所有奇环的交上的边. 考虑怎么找这些边.跑一遍dfs造出dfs树,找出返祖边构成的奇环.可以通 ...
- bzoj千题计划229:bzoj4424: Cf19E Fairy
http://www.lydsy.com/JudgeOnline/problem.php?id=4424 图是二分图的条件:没有奇环 所以,如果图不存在奇环,删除任意一条边都可以 如果存在奇环, 对于 ...
- 【BZOJ-4326】运输计划 树链剖分 + 树上差分 + 二分
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 703 Solved: 461[Submit][Status] ...
- [luogu P3128][USACO15DEC]Max Flow [LCA][树上差分]
题目描述 Farmer John has installed a new system of pipes to transport milk between the stalls in his b ...
- 树上差分 (瞎bb) [树上差分][LCA]
做noip2015的运输计划写了好久好久写不出来 QwQ 于是先来瞎bb一下树上差分 混积分 树上差分有2个常用的功能: (1)记录从点i到i的父亲这条路径走过几次 (2)将每条路径(s,t ...
- [填坑]树上差分 例题:[JLOI2014]松鼠的新家(LCA)
今天算是把LCA这个坑填上了一点点,又复习(其实是预习)了一下树上差分.其实普通的差分我还是会的,树上的嘛,也是懂原理的就是没怎么打过. 我们先来把树上差分能做到的看一下: 1.找所有路径公共覆盖的边 ...
- BZOJ4424: Cf19E Fairy
树上差分的代码很简洁,dfs+差分即可 这题很多坑点啊,比如重边自环好坑 #include<cstdio> #include<cstdlib> #include<algo ...
随机推荐
- 关于javascript 与iOS交互的简单使用
关于导入 JavaScriptCore 这个就不说了 js交互我们首先用到webView与webView的代理 基本上是很简单,,不过后台10分的坑 以下是代码 在webView的加载完成里面 fun ...
- N!,斯特林近似
题目链接 输入N求N的阶乘的10进制表示的长度.例如6! = 720,长度为3. Input 第1行:一个数T,表示后面用作输入测试的数的数量.(1 <= T <= 1000) 第2 - ...
- js函数参数理解
eg: function setName(obj){ obj.name = "Nicholas"; obj = new Object(); obj.name = "Gre ...
- size_type类型
由string类类型和vector类类型定义的类型,用以保存任意string对象或vector对象的长度,标准库类型将size_type定义为unsigned类型 string::size_type它 ...
- [转载]PyCharm创建.py自动添加文件头注释
转自:https://blog.csdn.net/qq_36482772/article/details/67218214 创建.py文件时 顺便自动添加作者.时间.文件名信息…… mac系统打开编辑 ...
- python字典对象的update()方法
使用字典对象的update()方法,如A.update(B),将B字典的键值对一次性全部添加到A字典对象,当A字典为空时,相当于深复制,非常方便.如果两个字典中存在相同的键,则进行值的更新. A={} ...
- 6、Java类、对象、构造器、引用类型内存基本知识、引用类型值传递
1.面向对象三大特征: 封装:encapsulation 继承:inheritance 多态:polymorphism 2.类中 数据特征(property):属性(attribute)静态的stat ...
- SQLSever: 怎样在select中的每一行产生不同的随机数?
select 的随机函数有点假, 或许是由于它是基于时间来的吧, 同一select中由于时间无法错开导致产生的随机数都是一样的. 怎样做到让不同的行拥有不同的随机数呢? 以下以产生某个月的随机日期来演 ...
- HDOJ 5296 Annoying problem LCA+数据结构
dfs一遍得到每一个节点的dfs序,对于要插入的节点x分两种情况考虑: 1,假设x能够在集合中的某些点之间,找到左边和右边距离x近期的两个点,即DFS序小于x的DFS序最大点,和大于x的DFS序最小的 ...
- 【试水CAS-4.0.3】第02节_CAS服务端登录页个性化
完整版见https://jadyer.github.io/2015/07/16/sso-cas-login-diy/ /** * @see ------------------------------ ...