二分图的染色法判定
二分图的染色法判定
二分图的定义:如果一张无向图的 \(n\) 个顶点可以分为 \(A,B\) 两个不相交的集合,并且同一集合内的所有点之间没有边相连,记这张特征图为二分图
\(\implies\) 每一条边都是连接两个集合的边,所以从一个集合出发需要经过偶数条边才能走回原来的集合
推理:二分图不存在奇环(边数为奇数的环)
二分图的判定:染色法,用两种不同的颜色标记整张图,当一个节点被颜色 \(1\) 标记后,那么它相邻的节点会被标记颜色 \(2\) ,如果标记过程中,存在颜色冲突,那么图中存在奇环
int n,m;
vector<int> e[N];
cin>>n>>m;
for (int i=1;i<=m;i++) {
int u,v;
cin>>u>>v;
e[u].push_back(v);
e[v].push_back(u);
}
因为不考虑每条边的边权,所以之间利用 vector<int> e[N] 存图,e[u]=v 表示 \(u\) 点到 \(v\) 点存在一条边
然后 DFS 对每个点尝试染色
int color[NN];//0表示没有被染色
bool dfs(int u,int c){//走到u点应该染c表示的颜色
color[u]=c;
for (auto v:e[u]){//遍历u点的邻点
if (!color[v]){//如果没有被染色
if (dfs(v,3-c)){//走到v点,dfs染3-c表示的颜色,c=1,3-c=2 c=2,3-c=1
return 1;//如果dfs递归后为1,向上回溯1表示存在奇环
}
}
if (color[v]==c)//如果冲突,递归结束,返回1,表示存在负环
return 1;
}
return 0;//0表示不存在奇环
}
对每个没有被染色的点进行一次 DFS ,直到整张图都被染色
bool f=0;//判断是否存在奇环
for (int i=1;i<=n;i++){
if (!color[i]){//如果没有被染色,那么从这个点开始dfs
if (dfs(i,1)){
f=1;
break;
}
}
}
例如洛谷P1330
题目要求的是找到最少的河蟹数量,使得每条边至少有一个端点被覆盖(河蟹占据),并且相邻的两个点不能同时有河蟹
这实际上等价于求图的一个顶点覆盖,且覆盖的顶点集合是一个独立集
所以需要记录每次 DFS 过程中两种颜色点的数量,取最小的累加答案
// Problem: P1330 封锁阳光大学
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1330
// Memory Limit: 125 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
#define cintie ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define Trd int T;cin>>T;while (T--)solve();
#define LLinf 9e18;
#define Iinf 2e9
#define LL long long
#define Lc p<<1
#define Rc p<<1|1
#define lc(x) tr[x].ch[0]
#define rc(x) tr[x].ch[1]
using namespace std;
int n,m;
vector<int> e[10010];
int color[10010];
int ans,cnt1,cnt2;
bool dfs(int u,int c){
color[u]=c;
if (c==1) cnt1++;
else cnt2++;
for (auto v:e[u]){
if (!color[v]){
if (dfs(v,3-c)){
return 1;
}
}
if (color[v]==c)
return 1;
}
return 0;
}
int main()
{
cin>>n>>m;
for (int i=1;i<=m;i++) {
int u,v;
cin>>u>>v;
e[u].push_back(v);
e[v].push_back(u);
}
bool f=0;
for (int i=1;i<=n;i++){
if (!color[i]){
cnt1=0,cnt2=0;
if (dfs(i,1)){
f=1;
break;
}
ans+=min(cnt1,cnt2);
}
}
if (f) cout<<"Impossible";
else cout<<ans;
return 0;
}

浙公网安备 33010602011771号