日常自闭(菜鸡qaq)。不过开心的是看了题解之后1A了。感觉这道题非常好,必须记录一下,一方面理清下思路,一方面感觉自己还没有完全领会到这道题的精髓先记下来以后回想。

题意:给定 n 个点,m 条边的无向图,可以从图中删除一条边,问删除哪些边可以使图变成一个二分图。

看到二分图,我们肯定会想到奇环。要删除一条边使得剩下的图变成二分图,那么必定剩下的图也不能存在奇环。所以要删除的边都必须经过所有的奇环。这比较好想,但是还有一个难想一点的条件,要删除的边也不能经过任何的偶环,这是因为如果这条边经过了偶环,哪怕删除了这条边剩下的边也会形成新的奇环。为什么呢?画一下图就发现,假定奇环长度为A,偶环长度为B,他们共享的边长度为C,那么他们能形成新的长度为A+B-2*C长度的环,显然这个数是奇数。

综上,能删除的边满足上诉两个条件。我们得到这样一个算法:对所有奇环的边+1,对所有偶环的边-1,最后边值等于奇环个数的就是满足条件的边。 那么我们可以考虑用差分完成这个事情,用d[x]代表dfs树进入x点的边的差分值。染色的过程差分,染完色之后计算便值即可。

当然这道题还没完,以上的过程我们只考虑了dfs树边的情况,但是返祖边(非树边)呢?我们继续思考:经过上面的思考我们还是只考虑奇环上的返祖边,仔细画图观察:在dfs搜索树上,一个奇环返祖边只会属于一个奇环。根据我们上边的结论:边必须要经过所有奇环,可以得到:奇环返祖边能满足条件当且仅当图上只有一个奇环。

接下来还得注意一个小细节:自环。自环我们可以当中奇环,但是这种奇环没有返祖边,所以我们得特殊处理。

呼呼,到这里我们终于能AC了。

细节详见代码以注释:

#pragma comment(linker,"/STACK:102400000,102400000")
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+;
int n,m,odd,rec,num,col[N],vis[N],tag[N],dfn[N];
vector<int> ans; int cnt=,head[N],nxt[N<<],to[N<<],id[N<<];
void add_edge(int x,int y,int z) {
nxt[++cnt]=head[x]; to[cnt]=y; id[cnt]=z; head[x]=cnt;
} void dfs1(int x,int t,int in) {
col[x]=t; dfn[x]=++num;
for (int i=head[x];i;i=nxt[i]) {
if (i==(in^)) continue; //这样能处理重边的情况
int y=to[i];
if (!col[y]) dfs1(y,-t,i);
else {
if (dfn[x]<dfn[y]) continue; //这是一个细节,dfn[x]比dfn[y]大的才是返祖边
if (col[x]==col[y]) { //奇环
odd++; rec=i;
tag[x]++; tag[y]--;
} else { //偶环
tag[x]--; tag[y]++;
}
}
}
} void dfs2(int x,int in) {
vis[x]=;
for (int i=head[x];i;i=nxt[i]) {
if (i==(in^)) continue;
int y=to[i];
if (!vis[y]) {
dfs2(y,i);
tag[x]+=tag[y]; //累计子树差分值得到 x入边值
}
}
if (tag[x]==odd) ans.push_back(in); //满足条件的边
} int main()
{
cin>>n>>m;
for (int i=;i<=m;i++) {
int x,y; scanf("%d%d",&x,&y);
if (x==y) { //特别处理自环的情况
odd++; add_edge(,,i); rec=cnt; continue;
}
add_edge(x,y,i); add_edge(y,x,i);
} for (int i=;i<=n;i++)
if (!col[i]) dfs1(i,,); //染色
for (int i=;i<=n;i++)
if (!vis[i]) dfs2(i,); //计算边值 if (odd==) {
cout<<m<<endl;
for (int i=;i<=m;i++) printf("%d ",i);
} else {
if (odd==) ans.push_back(rec); //奇环返祖边
cout<<ans.size()<<endl;
sort(ans.begin(),ans.end());
for (int i=;i<ans.size();i++) printf("%d ",id[ans[i]]);
}
return ;
}

Codeforces 19E&BZOJ 4424 Fairy(好题)的更多相关文章

  1. Codeforces Round #378 (Div. 2) D题(data structure)解题报告

    题目地址 先简单的总结一下这次CF,前两道题非常的水,可是第一题又是因为自己想的不够周到而被Hack了一次(或许也应该感谢这个hack我的人,使我没有最后在赛后测试中WA).做到C题时看到题目情况非常 ...

  2. Codeforces 828B Black Square(简单题)

    Codeforces 828B Black Square(简单题) Description Polycarp has a checkered sheet of paper of size n × m. ...

  3. HYSBZ(BZOJ) 4300 绝世好题(位运算,递推)

    HYSBZ(BZOJ) 4300 绝世好题(位运算,递推) Description 给定一个长度为n的数列ai,求ai的子序列bi的最长长度,满足bi&bi-1!=0(2<=i<= ...

  4. BZOJ第一页刷题计划

    BZOJ第一页刷题计划 已完成:67 / 90 [BZOJ1000]A+B Problem:A+B: [BZOJ1001][BeiJing2006]狼抓兔子:最小割: [BZOJ1002][FJOI2 ...

  5. http://codeforces.com/gym/100623/attachments E题

    http://codeforces.com/gym/100623/attachments E题第一个优化它虽然是镜像对称,但它毕竟是一一对称的,所以可以匹配串和模式串都从头到尾颠倒一下第二个优化,与次 ...

  6. http://codeforces.com/gym/100623/attachments H题

    http://codeforces.com/gym/100623/attachments H题已经给出来的,包括后来添加的,都累加得到ans,那么从1-ans都是可以凑出来的,如果ans<a[n ...

  7. Codeforces Round #612 (Div. 2) 前四题题解

    这场比赛的出题人挺有意思,全部magic成了青色. 还有题目中的图片特别有趣. 晚上没打,开virtual contest打的,就会前三道,我太菜了. 最后看着题解补了第四道. 比赛传送门 A. An ...

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

    参考:https://blog.csdn.net/heheda_is_an_oier/article/details/51131641 这个找奇偶环的dp1真是巧妙,感觉像tarjan一样 首先分情况 ...

  9. Guard Duty (medium) Codeforces - 958E2 || (bzoj 2151||洛谷P1792) 种树 || 编译优化

    https://codeforces.com/contest/958/problem/E2 首先求出N个时刻的N-1个间隔长度,问题就相当于在这些间隔中选K个数,相邻两个不能同时选,要求和最小 方法1 ...

随机推荐

  1. Win7装VS2015报错"安装包丢失或损坏"的解决办法

    在Win7上安装VS2015的过程中,可能会出现下图错误: 这种情况,多半是应为Win7里面缺少了两个证书: Microsoft Root Certificate Authority 2010 Mic ...

  2. 使用canvas时, 如何用相对单位(rem, rpx)来适配不同机型

    使用canvas的api时, 使用的都是绝对数值, 如: 方法传参是坐标位置,不带单位,如ctx.translate(10,10); 那么此时, 我就需要将rem或rpx 转换成 px; 首先, 获取 ...

  3. ivew-admin 导入excel

    1.使用上传组件 <Upload ref="upload" name="importData" action="/api/device/impo ...

  4. 前端导出excel表格

    前言近期项目有个新需求--将折线图表的数据加一个下载成excel表格的功能.以前下载功能都是调后台接口的,但是这个迭代,后台压力比较重,部分就交给了前端自己实现,下面就记录一下前端如何实现excel表 ...

  5. Python每日一题 003

    将 002 题生成的 200 个激活码(或者优惠券)保存到 MySQL 关系型数据库中. 代码 import pymysql import uuid def get_id(): for i in ra ...

  6. Delphi RegisterHotKey 设置系统热键

    Symbolic constant name Value (hexadecimal) Keyboard (or mouse) equivalent VK_LBUTTON 01 Left mouse b ...

  7. window10安装mysql-5.7.20-winx64.zip

    window10安装mysql--winx64.zip 原文 https://www.cnblogs.com/ericli-ericli/p/6916285.html D:\share\src\win ...

  8. 关于Burp Suite不能抓包的解决方法

    一.Burp Suite有时能抓到包,有时不能抓到包 解决方法: 出现这种问题的原因就是代理没有设置成全局的,只是设置成了局部的. 打开IE浏览器,依次打开工具->Internet 属性-> ...

  9. (转)Maven中的库(repository)详解 ---repository配置查找构件(如.jar)的远程库

    转:https://blog.csdn.net/taiyangdao/article/details/52287856 Maven中的库(repository)是构件(artifact)的集合.构件以 ...

  10. 线程类中使用spring注解报空指针异常

    springboot项目开发中,作为服务端,实现了线程类,在此类中添加spring注解@Source注入的service,报空指针异常. 查原因后,发现是线程中,不支持spring注解,因为sprin ...