hdu2444(二分图的判断和最大匹配)

题意:给出n个点,m条边,问是否是二分图,不是输出No,如果是输出二分图最大匹配。

思路:先判断是否是二分图。这里运用染色法,这里用的dfs(用bfs也可以),原理就是相连两点不能是同一种颜色

二分图最大匹配用匈牙利算法就行。具体看代码。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
int color[250];
int mat[250];
int used[250];
int n,m;
vector<int> ve[250];

bool dfs(int x,int c)//染色 
{
    color[x]=c;
    int s=ve[x].size();
    for(int i=0;i<s;i++)
    {
        if(color[ve[x][i]]==c)//相连点同样颜色,不是二分图 
            return false;
        if(color[ve[x][i]]==0&&!dfs(ve[x][i],-c))//相连点还未染色,搜索相连点 
            return false;
    }
    return true;
}

bool solve()//判断是否是二分图 
{
    memset(color,0,sizeof(color));
    for(int i=1;i<=n;i++)
    {
        if(!color[i])
        {
            if(!dfs(i,1))
                return false;
        }
    }
    return true;
}
//匈牙利算法 
bool find(int x)
{
    int s=ve[x].size();
    for(int i=0;i<s;i++)
    {
        int v=ve[x][i];
        if(!used[v])
        {
            used[v]=1;
            if(!mat[v]||find(mat[v]))
            {
                mat[v]=x;
                return true;
            }
        }
    }
    return false;
}

int match()
{
    int ans=0;
    memset(mat,0,sizeof(mat));
    for(int i=1;i<=n;i++)
    {
        memset(used,0,sizeof(used));
        if(find(i))
            ans++;
    }
    return ans;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        int u,v;
        for(int i=1;i<=n;i++)
            ve[i].clear();
        for(int i=0;i<m;i++)
        {
            scanf("%d%d",&u,&v);
            ve[u].push_back(v);
            ve[v].push_back(u);
        }    
        if(!solve())
            printf("No
");
        else
            printf("%d
",match()/2);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/xiongtao/p/11170718.html