题面

Description

给定nnn个点,mmm条边的无向图(无自环),可以从图中删除一条边,问删除哪些边可以使图变成一个二分图。

Input

第111行包含两个整数nnn,mmm,分别表示点数和边数。

第2∼m+12\sim m+12∼m+1行每行两个数xxx,yyy,表示有一条边连接点xxx,yyy。

Output

第一行两个整数,表示能删除的边的个数。

接下来一行按照从小到大的顺序输出能删除的边的编号。

Sample Input

4 4
1 2
1 3
2 4
3 4

Sample Output

4
1 2 3 4

HINT

10%10\%10%的数据,n,m&lt;=10n,m&lt;=10n,m<=10

40%40\%40%的数据,n,m&lt;=1000n,m&lt;=1000n,m<=1000

70%70\%70%的数据,n,m&lt;=100000n,m&lt;=100000n,m<=100000

100%100\%100%的数据,n,m&lt;=2000000n,m&lt;=2000000n,m<=2000000

题解

考虑如何判断一个图是否为二分图:判断图中有无奇环,这可以用deepdeepdeep或colorcolorcolor(染色法)维护。

那么假设图中有kkk个奇环,要删掉一条边使得新图是二分图,就要把这kkk个奇环破坏或去掉,也就是把这kkk个奇环的共边中删掉任意一条。

也就是说,假设原图的某条边在所有的奇环上,就可以被删掉。

但还是有个问题,假设有一条边是两个奇环的共边,那么删掉这条边后两个奇环又会组成一个环,那这个环是奇是偶呢?

答案是偶,因为这个环的总点数等于原来两个奇环的点数之和减222,为偶数。

那我们就给每条边设一个numnumnum,如果有一个奇环经过这条边,就num[i]++num[i]++num[i]++,最后看一下这条边的numnumnum是否等于总奇环数就好了。

但这样找边会WA\color{red}{\mathrm{WA}}WA,为什么?

考虑下图的一种情况:

其中,红色边连着的是一个奇环,蓝色边连着的是一个偶环。

如果按照刚刚的理论,应该这些边都是可以删掉的:(1,2)(1,2)(1,2)、(1,3)(1,3)(1,3)、(2,3)(2,3)(2,3)。

可是我们发现,当我们删掉边(2,3)(2,3)(2,3)时,新图还是一个奇环(1⟶2⟶4⟶5⟶3⟶11\longrightarrow2\longrightarrow4\longrightarrow5\longrightarrow3\longrightarrow11⟶2⟶4⟶5⟶3⟶1)。

问题就在于,当一条边既在奇环上(设奇环点数为aaa,则aaa为奇数),又在偶环上时(设偶环点数为bbb,则bbb为偶数),删掉这条边后奇环和偶环会组成一个环,且点数为a+b−2a+b-2a+b−2,是个奇环。

所以当一条边既在奇环上又在偶环上时,我们不能选它。

所以我们还要给每条边设一个flagflagflag判断它在不在偶环上。

记得特判没有奇环的情况,这时任意删掉哪条边都可以。

最后代码如下:

#include<bits/stdc++.h>#define N 4000010using namespace std;int n,m,ans[N];
int cnt,tot,idx,top,head[N],nxt[N],to[N],id[N];
int col[N],num[N],st[N],dfn[N];
bool flag[N],vis[N],use[N];void adde(int u,int v,int ii)
{to[++cnt]=v;id[cnt]=ii;//id即这条边对应的是输入中的第几条nxt[cnt]=head[u];head[u]=cnt;
}void dfs(int u,int fa)
{dfn[u]=++idx;for(int i=head[u];i;i=nxt[i]){if(dfn[to[i]]>dfn[u]||to[i]==fa)continue;if(col[to[i]]!=-1)//如果已经访问过{if(col[to[i]]==col[u])//颜色相等即奇环{tot++;num[id[i]]++;for(int j=top;j&&to[st[j]]!=to[i];j--)//循环枚举环上的每一个点num[id[st[j]]]++;//记录num}else{//颜色不等即偶环for(int j=top;j&&to[st[j]]!=to[i];j--)flag[id[st[j]]]=true;//标记flag}continue;}col[to[i]]=col[u]^1;//染色st[++top]=i;//丢进stackdfs(to[i],u);st[top--]=0;//记得弹出来}
}void check(int u)
{vis[u]=true;for(int i=head[u];i;i=nxt[i]){if(!use[id[i]]&&((!flag[id[i]]&&num[id[i]]==tot)||!tot))//如果这条边还没有记录在答案里(去重),且没有奇环,或者这条边在所有奇环上且不在偶环上{use[id[i]]=true;ans[++ans[0]]=id[i];}if(!vis[to[i]])check(to[i]);}
}int main()
{memset(col,-1,sizeof(col));//每个点的颜色(初始化)scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){int u,v;scanf("%d%d",&u,&v);adde(u,v,i),adde(v,u,i);//建边}for(int i=1;i<=n;i++){if(col[i]==-1){tot=0;col[i]=0;dfs(i,-1);check(i);}}sort(ans+1,ans+ans[0]+1);printf("%d\n",ans[0]);for(int i=1;i<=ans[0];i++)printf("%d ",ans[i]);return 0;
}

【XSY2508】【BZOJ4424】Fairy(二分图)相关推荐

  1. 【BZOJ4424】Cf19E Fairy DFS树

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

  2. [二分图]Codeforces 19E. Fairy

    DescriptionDescription 你有一个nn个点mm条边的无向图. 对于每条边,判断删除之后是否为二分图. n,m≤104n,m\le10^4 SolutionSolution 一个图是 ...

  3. bzoj4424 Cf19E Fairy 树形dp

    题目描述: 给定 n 个点,m 条边的无向图,可以从图中删除一条边,问删除哪些边可以使图变成 一个二分图. n,m<=1000000 题目分析: 戳这里详细题解 一个二分图是没有奇环的. 要让所 ...

  4. BZOJ4424: Cf19E Fairy

    Description 给定 n 个点,m 条边的无向图,可以从图中删除一条边,问删除哪些边可以使图变成 一个二分图. Input 第 1 行包含两个整数 n,m.分别表示点数和边数. 第 2 到 m ...

  5. BZOJ4424 Cf19E Fairy(codeforces 19E/洛谷CF19E)

    树上差分 DFS BZOJ题目传送门 codeforces题目传送门 洛谷题目传送门 首先只有当图中没有奇环时一张图才能够二分图染色.因为只允许删一条边,那么答案就是所有奇环的交,并且奇环不能和偶环有 ...

  6. CodeForces - 19E Fairy【二分图】【DFS】

    题目链接:https://codeforces.com/contest/19/problem/E #include <iostream> #include <cstring> ...

  7. [codeforces19E]Fairy

    time limit per test : 1.5 seconds memory limit per test : 256 megabytes 分数:2800 Once upon a time the ...

  8. CodeForces 19E 仙女fairy

    CF19E 话说标题"仙女",好骚啊.... 这道题的题面核心是图论二分图.满足删除一条边,可以形成一张二分图.求可以删除的边数,并输出是那些边. 出题人非常良心的给出了前六十分的 ...

  9. POJ - 3041 Asteroids 二分图最小点覆盖

    题目链接 二分图一个很重要的定理:看了很多大神的博客表示看不懂为什么,以后再看 最小点覆盖=最大匹配 最小点覆盖就是在二分图里边,选择一个点,将所有与该点相链接的边删去,问最小找多少个点能够把所有的边 ...

最新文章

  1. 用java代码实现Singleton,为什么在Java代码中实现Singleton模式(有时被认为是Java世界中的反模式)?...
  2. leetcode-找出数组中重复的数字
  3. @RequestMapping和@GetMapping @PostMapping 区别
  4. 阿里云服务器部署php的laravel项目,在阿里云买ECS 搭建 Linux+Nginx+Mysql+PHP环境的
  5. wps出现安装installer_为什么不能安装WPS
  6. MySQL中Index Condition Pushdown(ICP)优化
  7. 组装台式电脑配置清单_萌新攒机必备!多价位台式电脑配置清单!
  8. 算法---回溯法--模板解法
  9. stringbuilder为什么线程不安全_String Builder 为什么线程不安全?
  10. bgp 建立邻居发送的报文_HCIE笔记-------BGP邻居状态详解
  11. authware链接html文件,authorware是什么软件?
  12. ubuntu 旺旺_Ubuntu 下通过Wine安装阿里旺旺并解决中文乱码
  13. 在计算机上最常用的英语单词,计算机常用英语单词
  14. SQL获取当天0点0分0秒和23点59分59秒方法
  15. 异常检测——线性模型
  16. 视频:忆童年有摇杆,《暗黑破坏神3》街机版演示
  17. 2019牛客多校训练营第一场 H题 HOR 题解
  18. “Handler中有Loop死循环,为什么没有阻塞主线程,原理是什么?”
  19. 短距离无线通讯-RFID
  20. 在Windows10上通过Virtualbox安装Ubuntu操作系统教程

热门文章

  1. 键盘拆开重新安装步骤_如何拆解与并重新组装你的笔记本电脑
  2. 数据库原理及应用期末复习汇总(附某高校期末真题试卷)
  3. -Xms -Xmx等jvm参数的含义
  4. strcmp函数的C语言实现
  5. pulp platform 的搭建
  6. rust提示游戏安全违规_RUST 游戏启动不了 每次都是 Rust Launcher Error: Loading Error - Start Service failed (1450)...
  7. js截取数组slice() 和 splice() 的用法
  8. 比ping更强大的fping
  9. html表格上下居中
  10. Java经典面试题答案解析(1-80题)