二分图判断

【题意】一个图为二分图当且仅当图中不存在边数为奇数的环。两种操作,1 x,y加入一条边,2删去最后加入的边,每次操作判断该图是否为二分图。

【思路】并查集判二分图

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define maxn 1000006
using namespace std;
struct data{
    int u1,f1,dp1,u2,f2,dp2;
    data(int u1=0,int f1=0,int u2=0,int f2=0):u1(u1),f1(f1),dp1(dp1),u2(u2),f2(f2),dp2(dp2){};
}lin[maxn];
struct node{
    int v1,v2,dp1,dp2;
    node(int v1=0,int dp1=0,int v2=0,int dp2=0):v1(v1),dp1(dp1),v2(v2),dp2(dp2){};
}e[maxn];
int n,m,lst[maxn],da[10004<<1],dep[10004<<1];
bool f[maxn];
int get(){
    char c;while(!isdigit(c=getchar()));
    int v=c-48;while(isdigit(c=getchar()))v=v*10+c-48;
	return v;
}
int getfa(int x){while(da[x]!=x) x=da[x];return x;}
void add(int x,int y,int num){
    int a=getfa(x),b=getfa(y+n);
    if(dep[a]>dep[b])swap(a,b);
    int c=getfa(x+n),d=getfa(y);
    if(dep[c]>dep[d])swap(c,d);
    lin[num]=data(a,da[a],c,da[c]);
    e[num]=node(b,dep[b],d,dep[d]);
    da[a]=b;da[c]=d;
    if(dep[a]==dep[b])++dep[b];
    if(dep[c]==dep[d])++dep[d];
}
void del(int num){
    da[lin[num].u1]=lin[num].f1;
    dep[e[num].v1]=e[num].dp1;
    da[lin[num].u2]=lin[num].f2;
    dep[e[num].v2]=e[num].dp2;
}
void init(){
	int x,y,z,now;
    n=get();m=get();
    f[now=0]=1;
    for(int i=1;i<=(n<<1);++i)da[i]=i,dep[i]=1;
    for(int k=1;k<=m;++k){
		z=get();
	    if(z==1){
			lst[k]=now;now=k;
			x=get();y=get();
	        if(getfa(x)==getfa(y))f[now]=0;
	        else{
			    add(x,y,now);
			    f[now]=f[lst[now]];
			}
	    }
	    else{
		    del(now);
		    now=lst[now];
		}
		if(f[now])printf("YES\n");
		else printf("NO\n");
	}
}
int main(){
    init();
    return 0;
}

【注意】

1、要有并查集的删除操作,即记录每次加边前x,y结点的集合和深度。

2、深度小的连到深度大的可加快速度。

3、x与y+n连边,y与x+n连边,若出现两点在同一集合则不是二分图。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值