http://acm.hdu.edu.cn/showproblem.php?pid=2444

判断是否构成二分图,如果有则求最大匹配

二分图判断用染色法,一个dfs就出来,具体看代码

#include <iostream>
#include <cstdio>
using namespace std ;
int n,m ;
struct node{
    int s,t,nxt ;
}e[40005] ;
int head[205],cnt,match[205],vis[205] ;
void add(int s,int t)
{
    e[cnt].s=s ;
    e[cnt].t=t ;
    e[cnt].nxt=head[s] ;
    head[s]=cnt++ ;
}
int cheak(int s,int v)
{
    for(int i=head[s] ;i!=-1 ;i=e[i].nxt)
    {
        int tt=e[i].t ;
        if(!vis[tt])
        {
            vis[tt]=-v ;
            if(!cheak(tt,-v))
                return 0 ;    
        }
        else
        {
            if(vis[tt]==v)
                return 0 ;    
        }
    }
    return 1 ;
}
int OK()
{
    memset(vis,0,sizeof(vis)) ;
    vis[1]=1 ;
    if(cheak(1,1))
        return 1 ;
    return 0 ;
}
int dfs(int s)
{
    for(int i=head[s] ;i!=-1 ;i=e[i].nxt)
    {
        int tt=e[i].t ;
        if(!vis[tt])
        {
            vis[tt]=1 ;
            if(match[tt]==-1 || dfs(match[tt]))
            {
                match[tt]=s ;
                return 1 ;
            }
        }
    }    
    return 0 ;
}
int max_match()
{
    int ans=0 ;
    memset(match,-1,sizeof(match)) ;
    for(int i=1 ;i<=n ;i++)
    {
        memset(vis,0,sizeof(vis)) ;
        ans+=dfs(i) ;
    }
    return ans ;
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        cnt=0 ;
        memset(head,-1,sizeof(head)) ;
        for(int i=0 ;i<m ;i++)
        {
            int s,t ;
            scanf("%d%d",&s,&t) ;
            add(s,t) ;
        }
        if(!OK())puts("No") ;
        else
            printf("%d\n",max_match()) ;
    }
    return 0 ;
}
View Code