定义
无向图可以分成两个点集,集合内的点不相连通,不允许存在奇环
// 二分图的判定
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10, M = 2e6 + 10;
struct
{
int to, next;
}e[M];
int top, h[N], color[N], n, m;
void add(int x, int y)
{
e[++top] = {y, h[x]};
h[x] = top;
}
bool dfs(int x, int c)
{
color[x] = c;
for (int i = h[x]; i ; i = e[i].next)
{
int y = e[i].to;
if (!color[y])
{
if (dfs(y, (c == 1 ? 2 : 1))) return true;
}
else if (color[y] == c) return true;
}
return false;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= m; i ++)
{
int x, y;
cin >> x >> y;
add(x, y);
add(y, x);
}
bool flag = false;
for (int i = 1; i <= n; i ++)
{
if (!color[i])
if (dfs(i, 1))
{
flag = true;
break;
}
}
cout << (flag ? "No" : "Yes");
return 0;
}
运用
二分图染色
P1330 封锁阳光大学
可以把这题抽象为:给出一些初始为白色的点和一些连边,现要把一些点染成黑色,使白点和黑点都不会相邻,求最小染色数。
考虑不成立时,肯定出现奇环,跑二分图的判定即可。
考虑成立时,对于图中的每个子二分图,染色后分成两个黑白点集;
根据判定,手模一下易发现,每个子二分图的最小染色数就是取黑白点的更小值。
\(O(n+m)~\) down.
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10, M = 2e5 + 10;
struct
{
int to, next;
}e[M];
int top, h[N], color[N], n, m;
void add(int x, int y)
{
e[++top] = {y, h[x]};
h[x] = top;
}
bool dfs(int x, int c, int & wh, int & bl)
{
color[x] = c;
if (c == 1) wh ++;
else bl ++;
for (int i = h[x]; i ; i = e[i].next)
{
int y = e[i].to;
if (!color[y])
{
if (dfs(y, (c == 1 ? 2 : 1), wh, bl)) return true;
}
else if (color[y] == c) return true;
}
return false;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= m; i ++)
{
int x, y;
cin >> x >> y;
add(x, y);
add(y, x);
}
bool flag = false;
int ans = 0;
for (int i = 1; i <= n; i ++)
{
if (!color[i])
{
int white = 0, black = 0;
if (dfs(i, 1, white, black))
{
flag = true;
break;
}
else
ans += min(white, black);
// printf ("i = %d white = %d black = %d\n", i, white, black);
}
}
if (flag) cout << "Impossible";
else cout << ans;
return 0;
}
标签:二分,return,int,top,笔记,学习,color,add,false
From: https://www.cnblogs.com/hi-zwjoey/p/17630956.html