[CF19E]Fairy

题意:给一个图,问删除哪些边可以让原图变为二分图

继续旧题补档,这题当时打比赛加强到了$2000000$

一个图是二分图当且仅当它不含奇环,所以我们要做的就是删边以破坏奇环

对图dfs,得到dfs树,此时非树边只会是返祖边,返祖边+树上路径可以构成环,我们把这种环称为“简单环”

如果没有简单奇环,那么它本来就是二分图,删掉任意一条边还是二分图

如果只有$1$个简单奇环,那么构成这个简单奇环的返祖边是可以删的

一条树边能删当且仅当所有奇环经过它而且没有偶环经过它,因为既要破坏所有奇环又不能构成新的奇环

统计奇环偶环直接dfs时差分统计即可

#include<stdio.h>
#include<algorithm>
using namespace std;
int h[2000010],to[4000010],nex[4000010],fa[2000010],dep[2000010],fae[2000010],d1[2000010],d2[2000010],s1[2000010],s2[2000010],ans[2000010],cnt,o,e,n,m,o1;
void add(int a,int b,int i){
	to[i]=b;
	nex[i]=h[a];
	h[a]=i;
	i+=m;
	to[i]=a;
	nex[i]=h[b];
	h[b]=i;
}
int down(int x){
	if(x>m)x-=m;
	return x;
}
void dfs(int x){
	for(int i=h[x];i;i=nex[i]){
		if(dep[to[i]]==0){
			dep[to[i]]=dep[x]+1;
			fa[to[i]]=x;
			fae[to[i]]=down(i);
			dfs(to[i]);
			s1[x]+=s1[to[i]];
			s2[x]+=s2[to[i]];
		}else if(to[i]!=fa[x]&&dep[x]>dep[to[i]]){
			if((dep[x]-dep[to[i]])&1){
				e++;
				d2[x]++;
				d2[to[i]]--;
			}else{
				o++;
				d1[x]++;
				d1[to[i]]--;
				o1=down(i);
			}
		}
	}
	s1[x]+=d1[x];
	s2[x]+=d2[x];
}
int rev(int x){
	if(x>m)return x-m;
	return x+m;
}
int gao(int x){
	if(fa[to[x]]==to[rev(x)])return to[x];
	if(fa[to[rev(x)]]==to[x])return to[rev(x)];
	return 0;
}
int main(){
	int i,x,y;
	scanf("%d%d",&n,&m);
	for(i=1;i<=m;i++){
		scanf("%d%d",&x,&y);
		add(x,y,i);
	}
	for(i=1;i<=n;i++){
		if(dep[i]==0){
			dep[i]=1;
			dfs(i);
		}
	}
	if(o==0){
		printf("%d\n",m);
		for(i=1;i<=m;i++)printf("%d ",i);
		return 0;
	}
	if(o==1){
		cnt=1;
		ans[1]=o1;
	}
	for(i=1;i<=m;i++){
		x=gao(i);
		if(x){
			if(s1[x]==o&&s2[x]==0){
				cnt++;
				ans[cnt]=i;
			}
		}
	}
	printf("%d\n",cnt);
	sort(ans+1,ans+cnt+1);
	for(i=1;i<=cnt;i++)printf("%d ",ans[i]);
}

原文地址:https://www.cnblogs.com/jefflyy/p/8449665.html

时间: 2024-10-23 22:53:11

[CF19E]Fairy的相关文章

【BZOJ4424】Cf19E Fairy DFS树

[BZOJ4424]Cf19E Fairy Description 给定 n 个点,m 条边的无向图,可以从图中删除一条边,问删除哪些边可以使图变成一个二分图. Input 第 1 行包含两个整数 n,m.分别表示点数和边数.第 2 到 m+1 行每行两个数 x,y 表示有一条(x,y)的边. Output 输出第一行一个整数,表示能删除的边的个数.接下来一行按照从小到大的顺序输出边的序号. Sample Input 4 4 1 2 1 3 2 4 3 4 Sample Output 4 1 2

bzoj千题计划229:bzoj4424: Cf19E Fairy

http://www.lydsy.com/JudgeOnline/problem.php?id=4424 图是二分图的条件:没有奇环 所以,如果图不存在奇环,删除任意一条边都可以 如果存在奇环, 对于树边来说: 那么可能可以删除的边一定在所有奇环的交集内 而且这条边不能在偶环内 因为如果一条边既是奇环上的一条边,又是偶环上的一条边 删除这条边后,这个奇环和偶环会合并成一个新的奇环 所以最终的答案= 奇环的交集-偶环的并集 对于非树边来说: 如果只有一个奇环,那么可以删除构成环的这条非树边 树边和

bzoj 4424: Cf19E Fairy &amp;&amp; codeforces 19E. Fairy【树形dp】

参考:https://blog.csdn.net/heheda_is_an_oier/article/details/51131641 这个找奇偶环的dp1真是巧妙,感觉像tarjan一样 首先分情况讨论,如果没有奇环,每条边都可以删:如果有一个奇环,奇环上隋边山:否则,删被所有奇环覆盖且没被任何一个偶环覆盖的边 那么重点就是怎样找到所有的奇环和偶环 用树形dp来搞,设f[i]记录经过第i条边的奇环数,g[i]记录经过第i条边的偶环数,因为是边的编号而存的是双向边,所以dp的时候用i>>1表示

ural 1343. Fairy Tale打表

1343. Fairy Tale Time limit: 1.0 secondMemory limit: 64 MB 12 months to sing and dance in a ring their celestial dance. One after another they hold a throne. The first is young and fierce January and the last is elderly and wise December. Leaving the

[jzoj]3506.【NOIP2013模拟11.4A组】善良的精灵(fairy)(深度优先生成树)

Link https://jzoj.net/senior/#main/show/3506 Description 从前有一个善良的精灵. 一天,一个年轻人B找到她并请他预言他的未来.这个精灵透过他的水晶球看到这个年轻人将要遇见一个非常美丽的公主并要娶她..精灵在一张纸上画了N个点并用一些线段将他们连起来,每条线段两端连着不同的点.画完了之后,精灵让年轻人去除一条线段.然后精灵尝试将每个点用红色或者蓝色进行染色,同时使得那里没有一条线段的两端是相同的颜色.如果精灵能够成功染色,这个预言就能成真.

codeforces 785C Anton and Fairy Tale

题目链接:http://codeforces.com/problemset/problem/785/C 题意:仓库容量是n,一开始是满的,然后每天晚上可以往仓库里装m粮食,最多装到n.然后每天白天有鸟来吃粮食,一只鸟吃1单位.第i天有i只鸟.问你多少天鸟可以把粮食吃完. 分析:一开始读错题,导致wa了两发.如果n<=m的话,只有n只鸟的时候一天把他吃完,输出n.如果m<n的话,前m是肯定吃不完的,m天之后,从1开始计数,就是好比每天白天吃i+m,晚上装m,一天好比加了i.所以可以二分天数,但是

[bzoj4424]Fairy

很久之前想写这题.结果还是把握不住CF的E,太神了啊....... 首先考虑的是二分图的性质,这个so easy,图中不存在奇数环. 然后分三种情况考虑: 1.只有一个奇数环,随便删除哪条 2.多个奇数环,删除它们都覆盖的那条 3.没有奇数环,岂不是爽爆了..? 然后还引入了“返祖边”的概念,这个具体可以看博客http://blog.csdn.net/DaD3zZ/article/details/50879626  太神了反正我一点都不会 其中详细叙述了删哪条,怎么删的问题,类似于一个前缀和的思

ZOJ 3521 Fairy Wars oj错误题目,计算几何,尺取法,排序二叉树,并查集 难度:2

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3521 ATTENTION:如果用long long 减小误差,这道题只能用%lld读入 首先需要判断哪些点是相互挨着的,这样比直接维护哪些集合是冰冻住的简单 按照x为主,y为辅排序,在数组上尺取,当head与tail的x坐标相差大于l/2则把head向后移动直到x坐标满足条件, 那么对于head到tail,现在的问题就只剩下检测出哪些点之间y间距小于l/2,把它们都按照p

NSOJ A fairy tale of the two(最小费用最大流、SPFA版本、ZKW版本)

n,m<=20,给两个n×m布尔矩阵,每次操作可将第一个矩阵的2个相邻元素互换.输出最少操作次数使得两个矩阵完全一样. 比赛的时候想过按照二分图完美匹配的类似做法构图,不过想到边太多以及卡各种题卡得没脾气,就先放放等赛后搞了... 看题解发现有更好的构图,所以就算当时搞了也是TLE.... 先对所有格子及其上下左右连条流量为inf,费用为1的边,表示使用这条边每次是花费1个操作. 然后将第一个矩阵为1的点连S,流量为1,费用0,表示这个1可以用于满足第二个矩阵的某一个需要 第二个矩阵为1的点连T