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 ...
随机推荐
- Mac系统升级后在终端输入git命令时遇到的问题
Mac系统升级git会找不到并且报错:xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools) ...
- vue过渡动画效果
1 过渡基础 1.1 过渡的方式 Vue 在插入.更新或者移除 DOM 时,提供多种不同方式的应用过渡效果. 包括以下工具: 在 CSS 过渡和动画中自动应用 class 可以配合使用第三方 CSS ...
- Yii 2.0.6 - 从入口到Action执行
defined('YII_DEBUG') or define('YII_DEBUG', true); defined('YII_ENV') or define('YII_ENV', 'dev'); r ...
- Hadoop(8)-HDFS的读写数据流程以及机架感知
1. HDFS的写数据流程 1.客户端通过fs模块向NameNode申请文件上传,NameNode检查请求是否合法,如用户权限,目标文件是否已存在,父目录是否存在等等 2.NameNode返回是否可以 ...
- 日志管理——rsyslog
官方文档(必看) http://www.rsyslog.com/doc/v8-stable/ 简介 rsyslog是linux自带日志管理工具,分为客户端\服务端,包含日志收集\过滤\分析\转储. 数 ...
- No configuration found for this host:al
想尝试多个agent来进行传输数据其中的一个配置文件如下: al.sources = r1al.sinks = k1al.channels = c1 al.sources.r1.type = avro ...
- 07 json与os模块(进阶)
json和os模块 阶段一 .数据交换 1.json的基本介绍 JSON全名是JavaScript Object Notation(即:JavaScript对象标记)它是JavaScript的子集. ...
- Spring BindingResult验证框架Validation特殊用法
使用注解@Valid(实体属性校验) Springboot实现 Spring实现 一.准备校验时使用的JAR validation-api-1.0.0.GA.jar:JDK的接口: hibernate ...
- (数据科学学习手札01)Python与R基本数据结构之异同
Python 1.列表(list) list1 = [i for i in range(10)] list1[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 特点:可遍历,可索引,可切片 ...
- 【动态规划】[UVA1025]A Spy in the Metro 城市里的间谍
参考:https://blog.csdn.net/NOIAu/article/details/71517440 https://blog.csdn.net/c20180630/article/deta ...