CF19 E Fairy——树上差分
题目:http://codeforces.com/contest/19/problem/E
先把图连成一棵树,然后对于每条非树边,判断它是在奇环中还是偶环中;
把环上的点打上相应的差分标记,并记录有多少个奇环;
dfs 出来后判断,若没有奇环,那么所有边都可以删;
若有奇环 k 个,遍历边,在 k 个奇环中而不在偶环中的边可以删;
如果一条边既在奇环中又在偶环中,那么若删掉它,原来的一奇环一偶环会合并成一个大奇环,所以这种边不能删;
写、调了整整两小时,改了许多冗余的地方和错误的地方才终于A了,我这代码能力...
码力++!
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int const maxn=2e4+;
int n,m,fa[maxn],sf[maxn],sg[maxn],g[maxn],f[maxn],ans[maxn],ns;
int col[maxn],hd[maxn],ct,cnt,qhd[maxn],numj;
bool vis[maxn];
struct N{
int to,nxt,edge;
N(int t=,int n=,int e=):to(t),nxt(n),edge(e) {}
}ed[maxn<<],q[maxn];
struct T{
int ff,gg;
T(int f=,int g=):ff(f),gg(g) {}
};
inline int rd()
{
int ret=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-; ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return ret*f;
}
inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
inline void add(int x,int y,int e){ed[++ct]=N(y,hd[x],e); hd[x]=ct;}
inline void ad(int x,int y,int e){q[++cnt]=N(y,qhd[x],e); qhd[x]=cnt;}
inline void dfs2(int x,int pre)
{
vis[x]=; col[x]=!col[pre];
for(register int i=qhd[x];i;i=q[i].nxt)
{
int u=q[i].to;
if(!vis[u])continue;
int lca=find(u);
if(col[u]==col[x])
{
// f[u]++,f[i]++,f[pr[lca]]-=2,numj++;
f[u]++,f[x]++,f[lca]-=,numj++;
sf[q[i].edge]=;
}
else
{
// g[u]++,g[i]++,g[pr[lca]]-=2,numo++;
g[u]++,g[x]++,g[lca]-=;
}
}
for(register int i=hd[x],u;i;i=ed[i].nxt)
if((u=ed[i].to)!=pre)dfs2(u,x);
fa[x]=pre;
}
inline T dfs3(int x,int pre)
{
int smf=f[x],smg=g[x]; vis[x]=;//smf,smg!=0!!!
for(register int i=hd[x],u;i;i=ed[i].nxt)
{
if((u=ed[i].to)==pre)continue;
T k=dfs3(u,x);int e=ed[i].edge;
sf[e]=k.ff; sg[e]=k.gg;
smf+=k.ff; smg+=k.gg;
}
return T(smf,smg);
}
int main()
{
n=rd(); m=rd();
for(register int i=;i<=n;i++)fa[i]=i;
for(register int i=,u,v;i<=m;i++)
{
u=rd(); v=rd();
if(find(u)!=find(v))
{
fa[find(u)]=find(v);
add(u,v,i); add(v,u,i);
}
else ad(u,v,i),ad(v,u,i);
}
for(register int i=;i<=n;i++)fa[i]=i;
for(int i=;i<=n;i++)if(!vis[i])dfs2(i,);//不仅dfs(1,0)
memset(vis,,sizeof vis);
if(!numj)
{
printf("%d\n",m);
for(int i=;i<=m;i++)printf("%d ",i);
return ;
}
for(int i=;i<=n;i++)if(!vis[i])dfs3(i,);
memset(vis,,sizeof vis);
for(register int i=;i<=m;i++)
if(sf[i]==numj&&!sg[i])ans[++ns]=i;
printf("%d\n",ns);
sort(ans+,ans+ns+);
for(register int i=;i<=ns;i++)printf("%d ",ans[i]);
return ;
}
CF19 E Fairy——树上差分的更多相关文章
- CF 19E Fairy——树上差分
题目:http://codeforces.com/contest/19/problem/E 去掉一条边,使无向图变成二分图. 该边应该被所有奇环经过,且不被偶环经过. 因为一条非树边一定只在一个环里. ...
- CF19E Fairy(树上差分)
题目描述 很久很久以前,有一个仙女叫做A.有一天一个少年B找到她,并且请求她预测他的未来.仙女看着她的水晶球,说这位少年不久将遇见世界上最美丽的公主,并且将迎娶她为妻.然后仙女在一张纸上画了n个点,并 ...
- BZOJ4424/CF19E Fairy(dfs树+树上差分)
即删除一条边使图中不存在奇环.如果本身就是个二分图当然任意一条边都可以,先check一下.否则肯定要删除在所有奇环的交上的边. 考虑怎么找这些边.跑一遍dfs造出dfs树,找出返祖边构成的奇环.可以通 ...
- 【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.找所有路径公共覆盖的边 ...
- 【NOIP2016】【LCA】【树上差分】【史诗级难度】天天爱跑步
学弟不是说要出丧题吗>>所以我就研究了1天lca又研究了1天tj然后研究了一天天天爱跑步,终于写了出来.(最后的平均用时为240ms...比学弟快了1倍...) 题意:给你颗树,然后有m个 ...
- BZOJ_4238_电压_树上差分+dfs树
BZOJ_4238_电压_树上差分+dfs树 Description 你知道Just Odd Inventions社吗?这个公司的业务是“只不过是奇妙的发明(Just Odd Inventions)” ...
随机推荐
- java虚拟机(六)--垃圾收集器和内存分配策略
目前没有完美的收集器,不同的厂商.版本的虚拟机提供的垃圾收集器会有很大的差别,用户根据自己应用特点和要求组合出各个年代所使用 的收集器.基于jdk1.7Update14之后的虚拟机. HotSpot的 ...
- 洛谷——P1516 青蛙的约会
P1516 青蛙的约会 题目描述 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件 ...
- Linux---文件目录管理
1. Linux文件目录架构 Linux的目录结构与win的目录有很大不同,首先,没有盘符的概念:然后Linux使用斜杠/标识目录,Linux首先建立一个根目录,然后将其他文件系统挂载到这个目录下. ...
- Python基础之函数参数与返回值进阶
参数作用:如果外界希望在函数内部处理数据,就可以将数据作为参数传入函数内部: 返回值作用:如果希望一个函数函数执行完成后,向外界报告函数的执行结果,就可以使用函数的返回值. 函数的返回值 进阶 利用元 ...
- 51NOD 1183编辑距离(动态规划)
>>点击进入原题测试<< 思路:这个题放在基础题,分值还是零分,好歹也给人家动态规划一点面子啊!刚开始写的想法是找到其最大公共字串,然后用两个字符串中最长字符串的长度减掉最大公 ...
- print pdf bug & DOCTYPE
print pdf bug & DOCTYPE OK with <!DOCTYPE html> <!DOCTYPE html> <html lang=" ...
- POJ 2115 简单的模线性方程求解
简单的扩展欧几里得题 这里 2^k 不能自作聪明的用 1<<k来写 , k >= 31时就爆int了 , 即使定义为long long 也不能直接这样写 后来老老实实 for(int ...
- COJ 1411 Longest Consecutive Ones
题目大意: 希望在 k 步之内,将尽可能多的1移到相邻的位置上 这里依靠前缀和解决问题 我们用pos[i]保存第i个1的位置,这里位置我以1开始 用sum[i]保存前 i 个1从 0 点移到当前位置所 ...
- noip模拟赛 圆桌游戏
[问题描述] 有一种圆桌游戏是这样进行的:n个人围着圆桌坐成一圈,按顺时针顺序依次标号为1号至n号.对1<i<n的i来说,i号的左边是i+1号,右边是i-1号.1号的右边是n号,n号的左边 ...
- QT .pro文件的学习收获
1. 载pro文件预定义宏: CONFIG(debug,debug|release){ DEFINES+=__DEBUG__ }else{ DEFINES+=__RELEASE__ macx:DEST ...