二分图的定义和判定方法:
参考博客:二分图的定义和判定

染色法判定二分图

代码:

#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;
}

posted on 2019-09-28 16:31  Refused  阅读(52)  评论(0编辑  收藏  举报