• 图论——染色法判定二分图


      首先明确概念:

      二分图:设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。

      奇数环:一个图中边数为奇数的环。

      染色法原理:

      首先任意取出一个顶点进行染色,和该节点相邻的点有三种情况:

      1.如果未染色,那么继续染色此节点(染为另一种颜色)

      2.如果已染色但和当前节点颜色不同,则跳过该点

      3.如果已染色并且和当前节点颜色相同,返回失败(该图不是二分图)

      明确二分图、奇数环、染色法之间的关系:

      如果一个图中存在奇数环,那么这个图一定不是二分图;这一点显然成立。

      如果一个图中不存在奇数环,那么这个图一定是二分图:

      证明:用染色法。从某个点开始逐层交叉染色,在染色过程中:

        若发现有某条边的两个端点着色相同,则必定存在奇数环①,与题意相矛盾。

        若没有发现,则根据染色法原理,每一条边的两端着色必然不同,那么根据二分图的定义,就可知这个图是一个二分图。

        ①的证明:

          不妨设这条边的两个端点着色都为1,且这两点必然是由同一个源点扩展而来。那么根据染色法原理,因为这两个点的着色相同,那么从源点到这两个点所经过的边数(假设分别为x和y)的奇偶性必然相同,那么这个环的总边数为x+y+1,由数学知识得这个数必然是奇数。 

        证毕!

      模板题链接:染色法判定二分图

      代码如下:

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    const int N = 100010, M = 200010;
    struct Edge{
        int to,next;
    }edge[M];int cnt;
    int n,m;
    int h[N],color[N];
    
    void add_edge(int u,int v)
    {
        edge[++cnt].to=v;
        edge[cnt].next=h[u];
        h[u]=cnt;
    }
    
    bool dfs(int u,int c)
    {
        color[u]=c;
        for(int i=h[u]; ~ i;i=edge[i].next)
        {
            int to=edge[i].to;
            if(color[to]==c)
            {
                return false;
            }
            else if(!color[to]&&!dfs(to,3-c))return false;
        }
        return true;
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        memset(h,-1,sizeof h);
        for(int i=1;i<=m;i++)
        {
            int a,b;scanf("%d%d",&a,&b);
            add_edge(a,b);add_edge(b,a);
        }
        bool flag=true;
        for(int i=1;i<=n;i++)
        {
            if(!color[i])
            {
                if(!dfs(i,1))
                {
                    flag=false;
                    break;
                }
            }
        }
        if(flag)printf("Yes
    ");
        else printf("No
    ");
    }
  • 相关阅读:
    centos7.3 安装 mysql5.7.13
    linux下MySQL的启动与访问
    使用jquery修改display属性
    浏览器在线预览pdf、txt、office文件
    查看java的jar包源码
    邮件群发器
    公司招聘asp.net程序员(已过期)
    javascript面向对象,实现namespace,class,继承,重载
    javascript window.close() 去掉那讨厌的确认对话框
    如果注定要分别
  • 原文地址:https://www.cnblogs.com/ninedream/p/11203942.html
Copyright © 2020-2023  润新知