D24【模板】二分图判定 染色法
D24【模板】二分图判定 染色法_哔哩哔哩_bilibili
如果一张无向图的 N 个节点可以分成 A,B 两个不相交的非空集合,并且同一集合内的点之间没有边相连,称该无向图为二分图

定理:二分图不存在奇环(长度为奇数的环)或 二分图是可 2‑着色的
因为每一条边都是从一个集合走到另一个集合,只有走偶数次才可能回到同一个集合。左图是,右图不是
染色法判定二分图
当一个点被标记颜色 1 后,与它相邻的点都标记颜色 2,若标记过程产生冲突,则说明图中存在奇环
树、偶环、网格图等都是常见的二分图的例子
很多图论优化问题都可以在二分图上高效解决
- 极大团(平凡)
- 最小点着色(平凡)
- 最小边着色
- 最大匹配
- 最小边覆盖
- 最小点覆盖
- 最大独立集
- 最大权匹配
- 二分图博弈
U169194 【模板】二分图判定 - 洛谷 U248878 染色法判定二分图 - 洛谷
// 染色法判定二分图 O(n+m) #include<bits/stdc++.h> using namespace std; const int N=1005,M=2000005; int to[M],ne[M],h[N],idx; void add(int a,int b){ to[++idx]=b; ne[idx]=h[a]; h[a]=idx; } int n,m,color[N]; //color[u]=0,1,2 bool dfs(int u,int c){ //u点,u的颜色 color[u]=c; for(int i=h[u];i;i=ne[i]){ int v=to[i]; if(!color[v]){ //若v未染色 if(dfs(v,3-c)) return 1; //搜索v,给v染不同色,若有奇环则返回1 } else if(color[v]==c) return 1; //若v已染色且与u同色,说明有奇环则返回1 } return 0; //已搜完u的邻点没有奇环,则返回0 } int main(){ int T; cin>>T; for(int i=1;i<=T;i++){ memset(h,0,sizeof h); idx=0; memset(color,0,sizeof color); cin>>n>>m; for(int i=0,a,b;i<m;i++){ cin>>a>>b;add(a,b);add(b,a); } bool ok=true; //是二分图 for(int i=1;i<=n;i++)if(!color[i])if(dfs(i,1)){ //有奇环 ok=false; break; } if(ok) printf("case %d: \nYes\n",i); else printf("case %d: \nNo\n",i); } return 0; }
浙公网安备 33010602011771号