BZOJ4424/CF19E Fairy(dfs树+树上差分)
即删除一条边使图中不存在奇环。如果本身就是个二分图当然任意一条边都可以,先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树+树上差分)的更多相关文章
- 【BZOJ4424】Cf19E Fairy DFS树
[BZOJ4424]Cf19E Fairy Description 给定 n 个点,m 条边的无向图,可以从图中删除一条边,问删除哪些边可以使图变成一个二分图. Input 第 1 行包含两个整数 n ...
- [BZOJ 4771]七彩树(可持久化线段树+树上差分)
[BZOJ 4771]七彩树(可持久化线段树+树上差分) 题面 给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色,其中第i个节点的颜色为c[i].如果c[i] ...
- BZOJ4771 七彩树(dfs序+树上差分+主席树)
考虑没有深度限制怎么做.显然的做法是直接转成dfs序上主席树,但如果拓展到二维变成矩形数颜色数肯定没法做到一个log. 另一种做法是利用树上差分.对于同种颜色的点,在每个点处+1,dfs序相邻点的lc ...
- bzoj千题计划229:bzoj4424: Cf19E Fairy
http://www.lydsy.com/JudgeOnline/problem.php?id=4424 图是二分图的条件:没有奇环 所以,如果图不存在奇环,删除任意一条边都可以 如果存在奇环, 对于 ...
- BZOJ2588 主席树 + 树上差分
https://www.lydsy.com/JudgeOnline/problem.php?id=2588 题意:强制在线的询问树链权值第K小(无修) 这种类似于第K小的题,一般容易想到主席树,但是树 ...
- Codechef Sad Pairs——圆方树+虚树+树上差分
SADPAIRS 删点不连通,点双,圆方树 非割点:没有影响 割点:子树DP一下 有不同颜色,所以建立虚树 在圆方树上dfs时候 如果当前点是割点 1.统计当前颜色虚树上的不连通点对,树形DP即可 2 ...
- BZOJ3331 压力 (圆方树+树上差分)
题意 略 题解 求路径上的割点. 然后就直接圆方树上差分 CODE #include <bits/stdc++.h> using namespace std; inline void rd ...
- BZOJ3331 [BeiJing2013]压力[圆方树+树上差分]
圆方树新技能get.具体笔记见图连通性问题学习笔记. 这题求无向图的必经点,这个是一个固定套路:首先,一张连通的无向图中,每对点双和点双之间是以一个且仅一个割点连接起来的(如果超过一个就不能是割点了) ...
- BZOJ4424: Cf19E Fairy
树上差分的代码很简洁,dfs+差分即可 这题很多坑点啊,比如重边自环好坑 #include<cstdio> #include<cstdlib> #include<algo ...
随机推荐
- Solr6.6.0添加IK中文分词器
IK分词器就是一款中国人开发的,扩展性很好的中文分词器,它支持扩展词库,可以自己定制分词项,这对中文分词无疑是友好的. jar包下载链接:http://pan.baidu.com/s/1o85I15o ...
- canvas画布——画八卦图
实例 创建一个圆形: var c=document.getElementById("myCanvas"); var ctx=c.getContext("2d") ...
- 一些matlab教程资源收藏,使用matlab编程的人还是挺多的
Matlab教程专题资源免费下载整理合集收藏 <MATLAB从入门到精通>高清文字版[PDF] 103.9MB 简体中文 <矩阵实验室>(Mathworks.Matlab.R2 ...
- uva 509 RAID!(磁盘数据)
来自 https://blog.csdn.net/su_cicada/article/details/80085318 习题4-7 RAID技术(RAID!, ACM/ICPC World Final ...
- Matplotlib 子图的创建
在matplotlib中,整个图像为一个Figure对象 在Figure对象中可以包含一个或者多个Axes对象 每个Axes对象相当于一个子图了 每个Axes(ax)对象都是一个拥有自己坐标系统的绘 ...
- 用ssh进行git clone出现 fatal: Could not read from remote repository.
问题:在通过MobaXterm进行ssh连接的服务器上用ssh进行git clone出现 fatal: Could not read from remote repository. 解决方法:prox ...
- poj_2339
参考:https://blog.csdn.net/yzl_rex/article/details/7600906 https://blog.csdn.net/acm_JL/article/detail ...
- JS正则表达式笔记
正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串.将匹配的子串替换或者从某个串中取出符合某个条件的子串等. 正则 描述 ...
- docker学习(一) 安装
一.什么是docker 参见https://baike.baidu.com/item/Docker/13344470?fr=aladdin 个人的理解是,通俗来说,就是相当于一个方便携带且个体独立的虚 ...
- 在WPF中自定义控件(3) CustomControl (上)
原文:在WPF中自定义控件(3) CustomControl (上) 在WPF中自定义控件(3) CustomControl (上) 周银辉 ...