二分图又称作二部图,是图论中的一种特殊模型。
G=(V, E)是一个无向图 如果G的顶点集V可分割为两个互不相交的子集X和Y,并且E中每 条边连接的两个顶点一个在X中,另一个在Y中,则称图G为二分 图,记为G=(X,Y,E)。
由定义可知,二分图的这两个部分中的任意两个顶点之间没有路径
无向图 G 为二分图的充分必要条件是,G 至少有两个顶点,且其所有回路的长度均为偶数。
Question:给定一个无向联通图,如何判定该图是否为一个二分图?
染色法:参考博文:http://www.cnblogs.com/1227xq/p/6826783.html
https://www.cnblogs.com/digitalhermit/p/5119908.html
(1) 二分图的判定 [邻接表]
对二分图的结点进行染色。如果处于同一组,则应该染成同色,否则为不同色。在染色过程中,如果发生矛盾,说明此图不是二分图。
这种方法就像涂颜色一样,相邻(若有边相连)则染成不同色,反之染成同色,若矛盾,则false,反之true
下面为自作代码+借鉴代码
邻接链表
#include<bits/stdc++.h> #define N 100000 using namespace std; struct node{ int to,next; }e[N]; int head[N],tot,n,m; bool vis[N],colar[N]; void add(int u,int v){ e[++tot].to=v;e[tot].next=head[u];head[u]=tot; } bool dfs(int k){ vis[k]=1; for(int i=head[k],v;i,v=e[i].to;i=e[i].next){ if(vis[v]==0){ colar[v]=!colar[k]; }else { if(colar[v]!=colar[k]) return true; } } }//判断函数退出,默认返回false int main() { cin>>n>>m; for(int i=1;i<=n;i++){ int u,v; cin>>u>>v;add(u,v);add(v,u); } for(int i=1;i<=n;i++){ if(vis[i]==0){ if(dfs(i)==1){ printf("NO\n"); break; } } }printf("YES\n"); return 0; }