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

摘要:
如果图中没有奇环,则该图必须是二部图。如果没有找到,那么根据着色原理,每条边两端的着色必须不同。然后根据二分图的定义,我们可以知道该图是二分图。模板问题链接:染色法确定的二分图的代码如下:#include<iostream>#incluse<algorithm>#inclaude<cstring>#in包括<cstdio>usingnamespacestd;常数N=100010,M=200010;structEdge{intto,next;}边缘[M];积分;整数,m;inth[N],颜色[N];voidadd_edge{edge[++cnt].to=v;edge[cnt].next=h[u];h[u]=cnt;}booldfs{color[u]=c;对于{intto=edge[i].to;如果{returnfalse;}艾尔塞夫(!

首先明确概念:

二分图:设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 namespacestd;
const int N = 100010, M = 200010;
structEdge{
    intto,next;
}edge[M];intcnt;
intn,m;
inth[N],color[N];

void add_edge(int u,intv)
{
    edge[++cnt].to=v;
    edge[cnt].next=h[u];
    h[u]=cnt;
}

bool dfs(int u,intc)
{
    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;
}

intmain()
{
    scanf("%d%d",&n,&m);
    memset(h,-1,sizeofh);
    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
");
}

免责声明:文章转载自《图论——染色法判定二分图》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇关于elasticsearch和kibana的时区和日期问题20145214 《信息安全系统设计基础》第11周学习总结下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C++ OI图论 学习笔记(初步完结)

矩阵图 使用矩阵图来存储有向图和无向图的信息,用无穷大表示两点之间不连通,用两点之间的距离来表示连通。无向图的矩阵图是关于主对角线对称的。 如图所示: 使用dfs和bfs对矩阵图进行遍历 多源最短路径问题 最短路径的方法Floyd算法: $n^2$遍深度或广度优先搜索 权值为一 Floyd算法(多源最短路)是全局最优的动态规划 其核心算法如下: for...

图论:二分图判定

我其实只是想练一练二分图判定的,但是翻到了一个这么个题。。 双栈排序早有耳闻,非常欣赏当年的出题水平,堪称经典 这个题AC的人一定是个天才 废话不多说,双栈排序的思路我就不介绍了,没有那个水平,直接来说说怎么二分图染色 bool color(int x,int cl) { c[x]=cl; for(int tmp=g[x];tmp;tmp...

从0开始 图论学习 邻接表 STL vector

邻接表表示 用vector实现 writer:pprp 代码如下: #include <bits/stdc++.h> using namespace std; const int maxn = 1000; struct node { int to; int w; node(int tt, int ww):to(tt),w...

有向图邻接矩阵的幂敛指数与周期【图论】

Description 定义有向图邻接矩阵A的周期为最小的d,使得存在正整数k,对于任意n>=k,都有(A^n=A^{n+d})最小的k称为A的幂敛指数。 现给出一个n个点,m条边有向图,求它的邻接矩阵的周期对10^9+7取模的结果。n<=100000,m<=200000 对于n<=200,m<=3000的数据,你还需要求出它...

【笔记】清北学堂图论专题day1-1基础图论

我又来反刍了。。。图的概念,图的特殊类型,图的最短路算法 特殊图的类型 1)树 ​ 无环 无向 连通图 2)森林 ​ 无环 无向 3)有向图的树 ​ 无环 连通 ​ a)外向树 ​ 所有的边由浅向深(由上向下指) ​ b)内向树 ​ 所有的边由深向浅指 ​ c)其他普通的有向图的树 ​ 注:有向图的内外由所选的树根决定 4)章鱼图(基环树) ​ 只有一个环...

图论及其应用——图

我们探索某个领域的知识,无不怀揣的核弹级的好奇心与求知欲,那么,今天,我们就将开始对图论的探索。观察一副《机械迷城》的一处谜题。 不得不承认,《机械迷城》这款解密游戏难度远胜于《纪念碑谷》,其中一个困难点就在于——《纪念碑谷》的目标是很明确的,但是《机械迷城》往往需要自己凭感觉设立目标。而这里的关卡的目标,就是堵住第三个出水口。为了解决这个谜题,如果不去考...