二分图(1)

二分图(1)

1.例题:染色法判断二分图

题目描述

给定一个 n 个点 m 条边的无向图,图中可能存在重边和自环。

请你判断这个图是否是二分图。

输入格式

第一行包含两个整数 \(n\)\(m\)

接下来 m 行,每行包含两个整数 \(u\)\(v\),表示点 \(u\) 和点 \(v\) 之间存在一条边。

输出格式

如果给定图是二分图,则输出 Yes,否则输出 No

数据范围

\(1≤n,m≤10^5\)

输入样例:

4 4
1 3
1 4
2 3
2 4

输出样例:

Yes

注:本题来源于AcWing第860题

2.思路

我们判断的是二分图,这时候我们就可以用染色法。

我们可以从任意一点开始染色,然后把这个点连通的所有点全都染成一样的颜色(用dfs进行)。

如果在染色的时候有冲突,就标记一下。

最后判断,如果没有标记就是二分图,有则不是。

3.代码

#include<iostream>
#include<cstring> 
using namespace std;
const int N=100005;
int n,m;
int h[N],e[2*N],ne[2*N],idx;//存边的两个数组要开两倍,因为是无向边 
int color[N];//染色数组 
void add(int a,int b){//邻接表加边操作(加了两次) 
    e[idx]=b;
    ne[idx]=h[a];
    h[a]=idx++;
    e[idx]=a;
    ne[idx]=h[b];
    h[b]=idx++;
}
bool dfs(int u,int c){
    color[u]=c;//先染色 
    for(int i=h[u];i!=-1;i=ne[i]){//遍历u所有能到达的边 
        int j=e[i];//遍历到的边 
        if(!color[j]){//如果没染色 
            if(!dfs(j,3-c)) return false;//就去染另一种颜色,不行的话就不是二分图 
        }
        else if(color[j]==c) return false;//如果一条边有两种颜色,就不行,也就不是二分图 
    }
    return true;//别忘了 
}
int main(){
    cin>>n>>m;
    memset(h,-1,sizeof(h));
    for(int i=1;i<=m;i++){
        int a,b;
        cin>>a>>b;
        add(a,b);
    }
    bool flag=true; 
    for(int i=1;i<=n;i++){
        if(!color[i])
            if(!dfs(i,1)){//如果染色失败 
            	flag=false;//那就打标记 
           	    break; 
            }
    }
    if(flag) cout<<"Yes";
    else cout<<"No";
    return 0; 
}

完~

又双叒叕水博客

如果觉得还不错的话,就点个赞吧,您的支持就是我最大的动力。

posted @ 2022-08-11 22:56  Rainforests  阅读(33)  评论(0编辑  收藏  举报