二分图染色,二分图匹配——HDU

题目链接

题目含义

给出很多一对数,代表这两个人认识

要你将这些人分成两堆,一堆中的人互不认识(就是判定无负环)

如果可以的话,问最大匹配

题目分析

二分图染色模板题

注意这里二分代表的两个集合都是n个学生,如果你建双向边,最后最大匹配数要除2

题目代码

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
typedef long long LL;
const int maxn=4e4+7;
struct edge{
    int to,next;
}e[maxn];
int head[207],tot,person[207];
bool vis[207];
void add(int u,int v){
    e[tot].to=v;
    e[tot].next=head[u];
    head[u]=tot++;
}
int n,m,a,b;
void init(){
    tot=0;
    memset(head,-1,sizeof(head));
    memset(person,0,sizeof(person));
}
bool bfs(){
    queue<int>q;
    bool col[207];
    q.push(1);
    col[1]=vis[1]=true;
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=head[u];i!=-1;i=e[i].next){
            int v=e[i].to;
            if(!vis[v]){
                vis[v]=true;
                col[v]=!col[u];
                q.push(v);
            }
            else {
                if(col[v]==col[u])return false;
            }
        }
    }return true;
}
bool find(int u){
    for(int i=head[u];i!=-1;i=e[i].next){
        int v=e[i].to;
        if(vis[v])continue;
        vis[v]=true;
        if(!person[v]||find(person[v])){
            person[v]=u;return true;
        }
    }return false;
}
int main(){
    while(~scanf("%d%d",&n,&m)){
        init();
        for(int i=1;i<=m;i++){
            scanf("%d%d",&a,&b);
            add(a,b);
        }
        if(!bfs())printf("No
");
        else{
            int sum=0;
            for(int i=1;i<=n;i++){
                memset(vis,false,sizeof(vis));
                if(find(i))sum++;
            }
            printf("%d
",sum);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/helman/p/11291016.html