二分图的定义和判定方法:
参考博客:二分图的定义和判定
染色法判定二分图
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
int h[maxn*2], to[maxn*2], nex[maxn*2], vis[maxn], tot = 0;
void add(int u, int v){
to[tot] = v;
nex[tot] = h[u];
h[u] = tot++;
}
int n, m, u, v;
bool dfs(int x, int c){
vis[x] = c;
for(int i = h[x]; ~i; i = nex[i]){
int j = to[i];
if(!vis[j]){
if(!dfs(j, 3-c))return false;
}
else if(vis[j] == c) {
return false;
}
}
return true;
}
int main(){
tot = 0;
scanf("%d %d", &n, &m);
memset(h, -1, sizeof h);
for(int i = 1; i <= m; i++){
scanf("%d %d", &u, &v);
add(u, v), add(v, u);
}
int flag = 0;
for(int i = 1; i <= n; i++){//可能存在不是一块的连通图
if(!vis[i]){
if(!dfs(i, 1)){
flag = 1;
break;
}
}
}
if(flag)puts("No");
else puts("Yes");
}
二分图的最大匹配
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
int h[maxn], to[maxn], nex[maxn], vis[maxn], match[maxn], tot = 0;
void add(int u, int v){
to[tot] = v;
nex[tot] = h[u];
h[u] = tot++;
}
int n1, n2, m, u, v;
bool dfs(int x){
for(int i = h[x]; ~i; i = nex[i]){
int j = to[i];
if(!vis[j]){
vis[j] = true;
if(!match[j] || dfs(match[j])){
match[j] = x;
return true;
}
}
}
return false;
}
int main(){
tot = 0;
scanf("%d %d %d", &n1, &n2, &m);
memset(h, -1, sizeof h);
for(int i = 1; i <= m; i++){
scanf("%d %d", &u, &v);
add(u, v);
}
int res = 0;
for(int i = 1; i <= n1; i++){
memset(vis, 0, sizeof vis);
if(dfs(i))res++;
}
printf("%d\n", res);
return 0;
}
题目:COURSES
代码:
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
const int maxn = 1e5+10;
int h[maxn], to[maxn], nex[maxn], vis[305]; //vis一定不要开太大
int match[maxn], tot = 0;
void add(int u, int v)
{
to[tot] = v;
nex[tot] = h[u];
h[u] = tot++;
}
int n, m, u, v;
bool dfs(int x)
{
for(int i = h[x]; ~i; i = nex[i])
{
int j = to[i];
if(!vis[j])
{
vis[j] = true;
if(!match[j] || dfs(match[j]))
{
match[j] = x;
return true;
}
}
}
return false;
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
tot = 0;
memset(match, 0, sizeof match);
scanf("%d %d", &m, &n);
memset(h, -1, sizeof h);
for(int i = 1; i <= m; i++)
{
int t, a;
scanf("%d", &t);
while(t--)
{
scanf("%d", &a);
add(i, a);
}
}
if(n < m)
{
puts("NO");
}
else
{
int res = 0;
for(int i = 1; i <= m; i++)
{
memset(vis, 0, sizeof vis);
if(dfs(i))res++;
}
if(res == m)puts("YES");
else puts("NO");
}
}
return 0;
}