图应用之二分图判定

二分图判定

什么是二分图?

我们逐步分析,首先将图中相邻顶点涂成不同颜色叫做图着色问题,然后使用最少的颜色数来解决图着色问题叫做这个图的最小着色数,最最小着色数为2的图叫做二分图
今天我们就来说一说如何判定一个图能否是二分图?例如下面的demo1的最小着色数为3,不是二分图。
demo1


算法分析

首先是输入,我们如何把一幅图输入进去?邻接表。
邻接表有多种实现方式,比如说二维数组,Graph[i][j]表示i顶点第j个顶点是什么,(这里我们使用Graph[i][0]存储i顶点的相邻顶点数)。

图应用之二分图判定_第1张图片
解决了输入问题之后,我们来到算法的核心部分:如何判断是不是二分图?
我们的大方向是:假设最小着色数是2,判断合不合理
基于这样的假设,我们发现,当一个顶点的颜色确定后,和它相邻的顶点颜色也就自然确定了,因此,选择一个顶点出发,依次确定相邻顶点的颜色,就能判断是不是两种颜色了,使用深度优先搜索能够轻松解决。
下面直接给出代码,分析在注释中给出。


代码分析

输入格式:  
顶点个数N  
相邻顶点数k   k个序号
......
输出格式:
YES(或NO)
#include 
#define MAX 1000
int Graph[MAX][MAX];//存储图的序号
int color[MAX];//存储各个顶点的颜色  1或-1
using namespace std;

int dfs(int point,int c)//把点point染成c色,并且从顶点point开始深度搜索,如果不满足就返回0
{
    color[point] = c;
    int i;
    for(i = 1;i <= Graph[point][0];i++) //对每一个相邻顶点判断
    {
        // 如果相邻顶点的颜色相同,则返回0
        if(color[Graph[point][i]] == c)  return 0;
        // 如果相邻顶点还没有染色,则染成-c,并深度搜索判断真假
        if(color[Graph[point][i]] == 0 && !dfs(Graph[point][i],-c)) return 0;
    }

    //如果所有顶点都满足,就返回1
    return 1;
}

int main(void)
{
    int N,i,j,flag = 1; // N是图顶点个数
    cin>>N;

    for(i = 0;i < N;i++){
        cin>>Graph[i][0];  //用Graph[i][0]来存储相邻顶点个数 
        for(j = 1;j <= Graph[i][0];j++){
            cin>>Graph[i][j];
        }
    }  //读取图

    for(i = 0;i < N;i++){
        if(color[i] == 0) //如果点i还没有染色,就染成1
        {
            if(!dfs(i,1)){  //如果判断为假,则退出
                cout<<"NO";
                flag = 0;
                break;
            }
        }
    }

    if(flag == 1) //如果判断为真,则输出YES
        cout<<"YES";

    return 0;
}

对于demo1,输出结果如下:
这里写图片描述


你可能感兴趣的:(数据结构,图论,二分图)