二分图判定+图染色解决(bfs+dfs)

二分图定义:

二分图也称二部图,是图论里的一种特殊模型,也是一种特殊的网络流。其最大的特点在于,可以将图里的顶点分为两个集合,且集合内的点没有直接关联,如下图所示。

在这里插入图片描述
判断二分图的常见方法是染色法:用两种颜色,对所有顶点逐个染色,且相邻顶点染不同的颜色,如果发现相邻顶点染了同一种颜色,就认为此图不为二分图。 当所有顶点都被染色,且没有发现同色的相邻顶点,就退出。

dfs解法:


#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdio>
#include <cstring>
#include <map>

#define INF  0Xfffffff
#define ll long long
using namespace std;
int G[201][201];
int color[201];
int px[201];
int py[201];

//二分图判断采用染色法

int dfs(int s,int c) //点,颜色
{
    color[s]=c;
    for (int i=1;i<=G[s][0];i++)
    {
        int v=G[s][i];
        if(color[v]==c) return 0;
        else if(color[v]==-1&&!dfs(v,c&&1)) return 0;
    }
    return 1;
}
int main()
{
   int n,m;
   while(scanf("%d %d",&n,&m)!=EOF)
   {
       for (int i=0;i<m;i++)
       {
           int u,v;
           cin>>u>>v;
           G[u][++G[u][0]]=v;
           G[v][++G[v][0]]=u;
           
       }
       memset(color,-1,sizeof(color));
       //-1代表没染色 0代表染0类颜色 1代笔染1类颜色
       //如果不是连通图的话就要几次for循环
       for (int i=1;i<=n;i++)
       {
           if(color[i]==-1) 
           {
               if(!dfs(i,1)) 
               {
                   cout<<"no"<<endl;
               }
           }
       }
       cout<<"Yes"<<endl;
   }
    return 0;
}

bfs解法:



#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdio>
#include <cstring>
#include <map>

#define INF  0Xfffffff
#define ll long long
using namespace std;
int G[201][201];
int color[201];
int px[201];
int py[201];

//二分图判断采用染色法

int bfs(int s) //点,颜色
{
    color[s]=1;
    queue<int>q;
    q.push(s);
    while(!q.empty())
    {
        s=q.front();
        q.pop();
        for (int i=1;i<=G[s][0];i++)
        {
            int v=G[s][i];
            if(color[v]==color[s])
            {
                return 0;
            }
            if(color[i]==-1)
            {
                color[i]==color[s]&&1;
                q.push(i);
            }
        }
    }
    return 1;
}
int main()
{
   int n,m;
   while(scanf("%d %d",&n,&m)!=EOF)
   {
       for (int i=0;i<m;i++)
       {
           int u,v;
           cin>>u>>v;
           G[u][++G[u][0]]=v;
           G[v][++G[v][0]]=u;
           
       }
       memset(color,-1,sizeof(color));
       //-1代表没染色 0代表染0类颜色 1代笔染1类颜色
       //如果不是连通图的话就要几次for循环
       for (int i=1;i<=n;i++)
       {
           if(color[i]==-1) 
           {
               if(!bfs(i,1)) 
               {
                   cout<<"no"<<endl;
               }
           }
       }
        cout<<"Yes"<<endl;
   }
 
    return 0;
}


  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值