码迷,mamicode.com
首页 > 其他好文 > 详细

二分图

时间:2020-09-16 12:29:33      阅读:29      评论:0      收藏:0      [点我收藏+]

标签:pre   color   元素   二分   mes   for   eof   相同   mem   

什么是二分图?

二分图,就是能把图内所有元素划分成两个集合,且集合内没有边相连的图

二分图有什么性质?

如果图中有奇数环,则该图不是二分图

  • 染色法求二分图
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010, M = 200010;

int n, m;
int e[M], ne[M], h[N], idx; //由于二分图通常是无向图,所以边数*2
int color[N]; // 标记点的颜色,0为未上色,染的颜色有1和2

void add(int a, int b)//链式前向星存图
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}

bool dfs(int u, int c)
{
    color[u] = c;    

    for (int i = h[u]; i != -1; i = ne[i])  //遍历e[u]这个点的所有出边
    {
        int j = e[i];   
        if (!color[j])  // 1:该点没有上色,上一个色;
        {
            if (!dfs(j, 3 - c)) return false;   //3-c:把1变成2, 把2变成1, 保证染的色不同
        }
        else if (color[j] == c) return false;  // 2:如果该点与出边的颜色相同,则表明有奇数环,则不是二分图
    }

    return true;
}

int main()
{
    scanf("%d%d", &n, &m);

    memset(h, -1, sizeof h);

    while (m -- )
    {
        int a, b;
        scanf("%d%d", &a, &b);
        add(a, b), add(b, a);
    }

    bool flag = true;
    for (int i = 1; i <= n; i ++ ) // 有的点可能不在一个连通块中,所以要把所有点遍历一遍
        if (!color[i])  // 如果该点未上色就染成1
        {
            if (!dfs(i, 1))
            {
                flag = false;
                break;
            }
        }

    if (flag) puts("Yes");
    else puts("No");

    return 0;
}

二分图

标签:pre   color   元素   二分   mes   for   eof   相同   mem   

原文地址:https://www.cnblogs.com/Z-aiyi/p/13604930.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!