CF19E Fairy(树上差分)
题目描述
很久很久以前,有一个仙女叫做A。有一天一个少年B找到她,并且请求她预测他的未来。仙女看着她的水晶球,说这位少年不久将遇见世界上最美丽的公主,并且将迎娶她为妻。然后仙女在一张纸上画了n个点,并把它们分为几个板块,每个板块以一些点为始,另一些点为终。画完这幅画,仙女要求少年擦掉之上的一个板块。然后她尝试给每个点画上红色或蓝色,让纸上没有板块有和它的结尾颜色一样的点。如果她能做到,这个预言将会成真。B想邂逅世界上最美丽的公主,所以他想要你帮助他。找到所有能帮助他邂逅公主的板块。
输入输出格式:
输入格式:
输入文件的第一行有两个整数:n——点数;m:板块个数。
接下来的m行有板块的描述。每一个描述有两个整数,用空格隔开——v,u——各点的编号(index),由此板块连接。没有板块在描述中会被描述两次。
输出格式:
输出文件的第一行输出数字k——答案中板块的数量。输出文件的第二行输出k个数字,以空格隔开————每个板块的编号,升序排列。每个编号只应被输出一次。板块从1开始编号,以输入的顺序为序。
题解
因为二分图没有奇环,我们就把奇环删掉就行了。
实际上需要分情况讨论:
当没有奇环时,随便删掉一条边即可。
当只有一个奇环时,删掉这个奇环上没有被偶环覆盖的边就行(因为把一个奇环和一个偶环的公共边删去还是一个奇环)
当有多条奇环时,删掉被所有奇环覆盖的且不被偶环覆盖的边。
代码细节很多具体看代码
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=;
int n,m,sum,ans,cnt;
int f[maxn],to[maxn<<],next[maxn<<],book[maxn<<],head[maxn],pa[maxn],pb[maxn],vis[maxn],dep[maxn];
int fa[maxn][],Log[maxn],pc[maxn],s1[maxn],s0[maxn],from[maxn],bok[maxn];
inline void add(int a,int b){
to[++cnt]=b;
next[cnt]=head[a];
head[a]=cnt;
}
void dfs1(int x){
vis[x]=;
for(int i=head[x];i;i=next[i])
if(!vis[to[i]])
book[i]=,fa[to[i]][]=x,dep[to[i]]=dep[x]+,from[to[i]]=(i>>),dfs1(to[i]);
}
int lca(int u,int v){
if(dep[u]<dep[v])swap(u,v);
for(int i=;i>=;i--){
if(dep[fa[u][i]]>=dep[v])u=fa[u][i];
}
if(u==v)return v;
for(int i=;i>=;i--){
if(fa[u][i]!=fa[v][i]){
u=fa[u][i];v=fa[v][i];
}
}
return fa[u][];
}
void dfs2(int x){
for(int i=head[x];i;i=next[i])
if(book[i])
dfs2(to[i]),s1[x]+=s1[to[i]],s0[x]+=s0[to[i]];
}
int main()
{
scanf("%d%d",&n,&m);
cnt=;
int i,j;
for(i=;i<=m;i++){
scanf("%d%d",&pa[i],&pb[i]);add(pa[i],pb[i]);add(pb[i],pa[i]);
}
for(i=;i<=n;i++) if(!vis[i]) dep[i]=,dfs1(i);
for(int i=;i<=;i++)
for(int j=;j<=n;j++){
fa[j][i]=fa[fa[j][i-]][i-];
}
for(i=;i<=m;i++)
if(!book[i*]&&!book[i*+]){
pc[i]=lca(pa[i],pb[i]);
if(!((dep[pa[i]]^dep[pb[i]])&))sum++,s1[pa[i]]++,s1[pb[i]]++,s1[pc[i]]-=;
else s0[pa[i]]++,s0[pb[i]]++,s0[pc[i]]-=;
}
for(i=;i<=n;i++)if(dep[i]==)dfs2(i);
if(!sum){
printf("%d\n",m);
for(i=;i<=m;i++)printf("%d ",i);
return ;
}
if(sum==)
for(i=;i<=m;i++)
if(!book[i*]&&!book[i*+]&&!((dep[pa[i]]^dep[pb[i]])&))bok[i]=,ans++;
for(i=;i<=n;i++)
if(s1[i]==sum&&!s0[i])bok[from[i]]=,ans++;
printf("%d\n",ans);
for(i=;i<=m;i++)
if(bok[i])printf("%d ",i);
return ;
}
CF19E Fairy(树上差分)的更多相关文章
- CF 19E Fairy——树上差分
题目:http://codeforces.com/contest/19/problem/E 去掉一条边,使无向图变成二分图. 该边应该被所有奇环经过,且不被偶环经过. 因为一条非树边一定只在一个环里. ...
- CF19 E Fairy——树上差分
题目:http://codeforces.com/contest/19/problem/E 先把图连成一棵树,然后对于每条非树边,判断它是在奇环中还是偶环中: 把环上的点打上相应的差分标记,并记录有多 ...
- BZOJ4424/CF19E Fairy(dfs树+树上差分)
即删除一条边使图中不存在奇环.如果本身就是个二分图当然任意一条边都可以,先check一下.否则肯定要删除在所有奇环的交上的边. 考虑怎么找这些边.跑一遍dfs造出dfs树,找出返祖边构成的奇环.可以通 ...
- bzoj千题计划229:bzoj4424: Cf19E Fairy
http://www.lydsy.com/JudgeOnline/problem.php?id=4424 图是二分图的条件:没有奇环 所以,如果图不存在奇环,删除任意一条边都可以 如果存在奇环, 对于 ...
- 【BZOJ-4326】运输计划 树链剖分 + 树上差分 + 二分
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 703 Solved: 461[Submit][Status] ...
- [luogu P3128][USACO15DEC]Max Flow [LCA][树上差分]
题目描述 Farmer John has installed a new system of pipes to transport milk between the stalls in his b ...
- 树上差分 (瞎bb) [树上差分][LCA]
做noip2015的运输计划写了好久好久写不出来 QwQ 于是先来瞎bb一下树上差分 混积分 树上差分有2个常用的功能: (1)记录从点i到i的父亲这条路径走过几次 (2)将每条路径(s,t ...
- [填坑]树上差分 例题:[JLOI2014]松鼠的新家(LCA)
今天算是把LCA这个坑填上了一点点,又复习(其实是预习)了一下树上差分.其实普通的差分我还是会的,树上的嘛,也是懂原理的就是没怎么打过. 我们先来把树上差分能做到的看一下: 1.找所有路径公共覆盖的边 ...
- BZOJ4424: Cf19E Fairy
树上差分的代码很简洁,dfs+差分即可 这题很多坑点啊,比如重边自环好坑 #include<cstdio> #include<cstdlib> #include<algo ...
随机推荐
- TYVJ 1541 八数码
Orz双向搜索的cy大神 我用的是hash 也蛮快的 //By SiriusRen #include <queue> #include <cstdio> using names ...
- mysql索引的注意事项
索引的优点 大大加快数据的查询速度 使用分组和排序进行数据查询时,可以显著减少查询时分组和排序的时间 创建唯一索引,能够保证数据库表中每一行数据的唯一性 在实现数据的参考完整性方面,可以加速表和表之间 ...
- Java获取环境变量和系统属性
Java获取服务器环境变量和JVM系统变量 当程序中需要使用与操作系统相关的变量(例如:文件分隔符.换行符)时,Java提供了System类的静态方法getenv()和getProperty() ...
- 【原创】JAVA word转html
import java.io.File; import com.jacob.activeX.ActiveXComponent; import com.jacob.com.Dispatch; impor ...
- STM8S103之中断优先级设置
STM8S的中断由中断控制器(ITC)控制.STM8所有IO都支持中断,分为PA~PE 5个组,每组IO对应一个中断服务函数(也就是每组IO只有一个向量).STM8没有专门的中断状态寄存器,所以只能通 ...
- JavaScript 中表达式和语句的区别
1.语句和表达式 JavaScript中的表达式和语句是有区别的.一个表达式会产生一个值,它可以放在任何需要一个值的地方,比如,作为一个函数调用的参数.下面的每行代码都是一个表达式: myvar3 + ...
- 洛谷P3567 [POI2014]KUR-Couriers 主席树
挺裸的,没啥可讲的. 不带修改的主席树裸题 Code: #include<cstdio> #include<algorithm> using namespace std; co ...
- 浅谈 MySQL的外键的作用
MySQL中外键的介绍: MySQL外键必须使用存储引擎为 innDB 其中MySAM 和MEMORYH这两种引擎不支持 由数据库自身保证数据一致性,完整性,更可靠,因为程序很难100%保证数据的 ...
- 洛谷P5160 WD与循环
我们看这段代码 int cnt = 0; for (int a_1 = 0; a_1 <= m; a_1++) { for (int a_2 = 0; a_1 + a_2 <= m; a_ ...
- root用户无法切换到cdh的hive账号上
在/etc/passwd中看到hive账号是登录的终端是/bin/false,而正常的用户配置的都是/bin/bash,因此在root账号su到hive也是没有用的 hive:x:111:111:Hi ...