即删除一条边使图中不存在奇环。如果本身就是个二分图当然任意一条边都可以,先check一下。否则肯定要删除在所有奇环的交上的边。

  考虑怎么找这些边。跑一遍dfs造出dfs树,找出返祖边构成的奇环。可以通过树上差分标记奇环上的边。

  但是这显然只包含了一部分奇环。注意到如果某条在奇环上的边同时也在一个偶环上,一定可以找到一个不包含这条边的奇环。并且图中所有其他奇环都是由所找到的奇环加上偶环得到的,所以这就是充分的了。

  数据中有重边自环,自环特判一下比较舒服,而任意一条重边都不可能在答案中(本身就是二分图除外)。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<map>
#include<cassert>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 1000010
map<int,int> f[N];
int n,m,p[N],t=-,fa[N<<],deep[N],cnt[][N<<],delta[][N],tot;
struct data{int to,nxt;
}edge[N<<];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
void dfs(int k,int from)
{
for (int i=p[k];~i;i=edge[i].nxt)
if (edge[i].to!=from)
if (deep[edge[i].to]&&deep[edge[i].to]<=deep[k])
{
int op=deep[k]-deep[edge[i].to]&;
tot+=op^;cnt[op][i]++;
delta[op][k]++,delta[op][edge[i].to]--;
}
else if (!deep[edge[i].to])
{
deep[edge[i].to]=deep[k]+;
dfs(edge[i].to,k);
}
}
int Count(int op,int k,int from)
{
int s=;
for (int i=p[k];~i;i=edge[i].nxt)
if (edge[i].to!=from&&!deep[edge[i].to])
{
deep[edge[i].to]=deep[k]+;
int d=Count(op,edge[i].to,k);
s+=d,cnt[op][i]+=d;
}
s+=delta[op][k];
return s;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj4424.in","r",stdin);
freopen("bzoj4424.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read(),m=read();
for (int i=;i<=n*;i++) fa[i]=i;
memset(p,,sizeof(p));
bool flag=;int sc=;
for (int i=;i<=m;i++)
{
int x=read(),y=read();
if (x!=y)
{
f[x][y]++,f[y][x]++;
addedge(x,y);if (x!=y) addedge(y,x);
fa[find(x)]=find(y+n),fa[find(x+n)]=find(y);
if (find(x)==find(y)) flag=;
}
else sc=sc?m+:i;
}
if (sc)
{
if (!flag||sc>m) {cout<<;return ;}
cout<<<<endl<<sc;
return ;
}
if (flag) {cout<<m<<endl;for (int i=;i<=m;i++) printf("%d ",i);return ;}
for (int i=;i<=n;i++) if (!deep[i]) deep[i]=,dfs(i,);
memset(deep,,sizeof(deep));
for (int i=;i<=n;i++) if (!deep[i]) deep[i]=,Count(,i,);
memset(deep,,sizeof(deep));
for (int i=;i<=n;i++) if (!deep[i]) deep[i]=,Count(,i,);
m=;
for (int i=;i<=t;i++) m+=(cnt[][i]==tot)&&(cnt[][i]==)&&(f[edge[i^].to][edge[i].to]==);
cout<<m<<endl;for (int i=;i<=t;i++) if ((cnt[][i]==tot)&&(cnt[][i]==)&&(f[edge[i^].to][edge[i].to]==)) printf("%d ",i/+);
return ;
}

BZOJ4424/CF19E Fairy(dfs树+树上差分)的更多相关文章

  1. 【BZOJ4424】Cf19E Fairy DFS树

    [BZOJ4424]Cf19E Fairy Description 给定 n 个点,m 条边的无向图,可以从图中删除一条边,问删除哪些边可以使图变成一个二分图. Input 第 1 行包含两个整数 n ...

  2. [BZOJ 4771]七彩树(可持久化线段树+树上差分)

    [BZOJ 4771]七彩树(可持久化线段树+树上差分) 题面 给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色,其中第i个节点的颜色为c[i].如果c[i] ...

  3. BZOJ4771 七彩树(dfs序+树上差分+主席树)

    考虑没有深度限制怎么做.显然的做法是直接转成dfs序上主席树,但如果拓展到二维变成矩形数颜色数肯定没法做到一个log. 另一种做法是利用树上差分.对于同种颜色的点,在每个点处+1,dfs序相邻点的lc ...

  4. bzoj千题计划229:bzoj4424: Cf19E Fairy

    http://www.lydsy.com/JudgeOnline/problem.php?id=4424 图是二分图的条件:没有奇环 所以,如果图不存在奇环,删除任意一条边都可以 如果存在奇环, 对于 ...

  5. BZOJ2588 主席树 + 树上差分

    https://www.lydsy.com/JudgeOnline/problem.php?id=2588 题意:强制在线的询问树链权值第K小(无修) 这种类似于第K小的题,一般容易想到主席树,但是树 ...

  6. Codechef Sad Pairs——圆方树+虚树+树上差分

    SADPAIRS 删点不连通,点双,圆方树 非割点:没有影响 割点:子树DP一下 有不同颜色,所以建立虚树 在圆方树上dfs时候 如果当前点是割点 1.统计当前颜色虚树上的不连通点对,树形DP即可 2 ...

  7. BZOJ3331 压力 (圆方树+树上差分)

    题意 略 题解 求路径上的割点. 然后就直接圆方树上差分 CODE #include <bits/stdc++.h> using namespace std; inline void rd ...

  8. BZOJ3331 [BeiJing2013]压力[圆方树+树上差分]

    圆方树新技能get.具体笔记见图连通性问题学习笔记. 这题求无向图的必经点,这个是一个固定套路:首先,一张连通的无向图中,每对点双和点双之间是以一个且仅一个割点连接起来的(如果超过一个就不能是割点了) ...

  9. BZOJ4424: Cf19E Fairy

    树上差分的代码很简洁,dfs+差分即可 这题很多坑点啊,比如重边自环好坑 #include<cstdio> #include<cstdlib> #include<algo ...

随机推荐

  1. Spring Boot2.0拦截器简单实现判断是否登录

    在进行项目开发的时候使用springboot框架用到拦截器时发现2.0以后原来的抽象类WebMvcConfigurerAdapter已经过时了,去官网查文档2.x版本要实现拦截器功能改为需要继承Web ...

  2. jquery图片滚动normalizy.css

    article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block; ...

  3. spring-运行时值注入

    在项目中经常使用连接数据库的配置,如下所示 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDa ...

  4. Ubuntu设置代理服务器

    由于公司网络的原因,apache的网站访问不了,对于需要经常访问apache网站查看文档的我,最近想了一种方法,在自己的阿里云服务器上搭建一个代理服务器.经过查资料,最终决定使用TinyProxy. ...

  5. Less Is More【少即是多】

    Less Is More Adults understand what it feels like to be flooed with objects. 成年人知道被物品淹没的感觉. Why do w ...

  6. 嵌入式框架Zorb Framework搭建七:任务的实现

    我是卓波,我是一名嵌入式工程师,我万万没想到我会在这里跟大家吹牛皮. 嵌入式框架Zorb Framework搭建过程 嵌入式框架Zorb Framework搭建一:嵌入式环境搭建.调试输出和建立时间系 ...

  7. 隐式Dijkstra:在状态集合中用优先队列求前k小

    这种技巧是挺久以前接触的了,最近又突然遇到几道新题,于是总结了一下体会. 这种算法适用的前提是,标题所述的"状态集合"大到不可枚举(否则枚举就行了qaq) ...

  8. Sqoop帮助文档

    1.列出MySql数据库中的所有数据库 $ sqoop list-databases --connect jdbc:mysql://192.168.254.105:3306/--username ro ...

  9. jmeter结合autoit操作windows程序

    需求: 模拟操作下图软件的控件,如拨号和挂机. 1. 下载安装好autoit后,打开finder tool,使用查找工具定位到要模拟操作的控件上,如图: 2.在finder tool中的control ...

  10. C# 获取当前日期当年的周数

    这几天跨年,项目上遇到了一个周数计算的问题. 2016年的元旦是周五开始的,之前系统计算的是属于15年的第53个周,但是年份已经到了16年了. 公司要求从1月1号周五开始算作16年的第一个周,今天1月 ...