bzoj 4424: Cf19E Fairy
来源:互联网 发布:模糊查询sql语句 编辑:程序博客网 时间:2024/05/16 18:36
题意:
给定 n 个点,m 条边的无向图,可以从图中删除一条边,问删除哪些边可以使图变成一个二分图。
题解:
关于二分图的性质:是一个要么无环,要么有偶环的图。
所以显然,在删掉那一条边后这个图不能有奇环。
我们定义奇环上不在生成树上的那一条边为返祖边。
则有一下几种情况:
1:没有奇环,则删任意一条边都可以。
2:只有一个奇环,那么可以删这个奇环上的任意一条边,且那条边不在偶环上。
为什么要考虑偶环呢,画图可以发现,如果删掉一条奇环偶环的公共边,那么原来的偶环就会形成新的奇环。
3:有多个奇环,那么所有返祖边都是不行的,那一条边一定要是所有奇环的公共边,同样的,也不能在偶环上。
所以dfs序搞一搞就出来了。
这题卡PE,有自环重边,图不一定连通,注意下。
code:
#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>using namespace std;struct node{ int x,y,d,next;}a[2000010];int len=0,last[1000010];int n,m;bool vis[1000010];int p[1000010],fa[1000010];int dep[1000010],tr[1000010][2];bool is_tr[1000010];int num=0,tmp;int ans[1000010],NUM=0,la[1000010],ys[1000010],z=0;void ins(int x,int y,int d){ a[++len].x=x;a[len].y=y;a[len].d=d; a[len].next=last[x];last[x]=len;}int lowbit(int x){return x&(-x);}void change(int x,int k,int rt){ for(int i=x;i<=n;i+=lowbit(i)) tr[i][rt]+=k;}int get(int x,int rt){ int ans=0; for(int i=x;i>=1;i-=lowbit(i)) ans+=tr[i][rt]; return ans;}void dfs(int x,int FA,int from){ vis[x]=true;fa[x]=FA;p[x]=from; ys[x]=la[x]=++z; is_tr[from]=true; dep[x]=dep[FA]+1; for(int i=last[x];i;i=a[i].next) { int y=a[i].y; if(is_tr[a[i].d]) continue; if(!vis[y]) dfs(y,x,a[i].d),la[x]=la[y]; else { if(dep[x]<dep[y]) continue; if((dep[x]-dep[y])%2==1) change(ys[y],-1,0),change(ys[x],1,0); else { num++;tmp=a[i].d; if(x!=y) change(ys[y],-1,1),change(ys[x],1,1); } } }}int getsum(int x,int rt){return get(la[x],rt)-get(ys[x]-1,rt);}bool cmp(int a,int b){return a<b;}int main(){ scanf("%d %d",&n,&m); for(int i=1;i<=m;i++) { int x,y;scanf("%d %d",&x,&y); ins(x,y,i); if(x!=y) ins(y,x,i); } memset(vis,false,sizeof(vis)); memset(is_tr,false,sizeof(is_tr)); for(int i=1;i<=n;i++) if(!vis[i]) dfs(i,0,0); if(num==0) { printf("%d\n",m); for(int i=1;i<m;i++) printf("%d ",i); if(m!=0) printf("%d",m); return 0; } for(int i=2;i<=n;i++) if(getsum(i,1)==num&&getsum(i,0)==0) ans[++NUM]=p[i]; if(num==1) ans[++NUM]=tmp; sort(ans+1,ans+NUM+1,cmp); printf("%d\n",NUM); for(int i=1;i<NUM;i++) printf("%d ",ans[i]); if(NUM!=0) printf("%d",ans[NUM]);}
阅读全文
1 0
- bzoj 4424: Cf19E Fairy
- bzoj 4424: Cf19E Fairy
- bzoj 4424: Cf19E Fairy dfs
- BZOJ 4424: Cf19E Fairy【强行树链剖分
- [二分图 dfs 打标记] BZOJ 4424 Cf19E Fairy
- CF19E Fairy
- BZOJ4424: Cf19E Fairy
- bzoj4424 Cf19E Fairy 树形dp
- BZOJ-4424 &&CodeForces-19E Fairy DP+dfs (Link-Cut-Tree可A)
- 【CodeForces19E】Fairy
- fairy tale(传奇)
- Ural 1343. Fairy Tale
- codeforces 19E Fairy
- Codeforces 19E Fairy
- Anton and Fairy Tale
- Anton and Fairy Tale
- codeforces 19E Fairy 树链剖分
- codeforces Anton and Fairy Tale
- js基本增删查
- (五)集合处理
- 带箭头的圆转动
- Laravel5.2 集成阿里云--OSS对象存储服务
- Java的由来
- bzoj 4424: Cf19E Fairy
- 【Android】高德定位错误总结
- STL
- Kubernetes的service mesh——第一部分:Service的重要指标
- AI说人“画” | 因果关系告诉你,爱笑的女孩运气不会太差?
- 安卓之小笔记
- RNN, LSTM简介
- codeblocks for windows
- 2017年10月8号