hdu2444(二分匹配)

来源:互联网 发布:c语言有哪些复合语句 编辑:程序博客网 时间:2024/06/05 02:14

题意:给出一些点以及一些边,问是否可分成二分图,如果可以输出大的集合的个数

思路:先判断是否是二分图,之后用匈牙利算法求最大匹配


#include <iostream>#include <cstdio>#include <cstdlib>#include <queue>#include <cstring>#define N 205using namespace std;int n,m,head[N],size,hd[N];int vis[N];struct node{    int v,next;}e[N*N];void init(){    memset(head,-1,sizeof(head));    memset(hd,-1,sizeof(hd));    size=0;}bool judge(int t){    for(int i=head[t];i!=-1;i=e[i].next)    {        if(!vis[e[i].v ])        {            vis[e[i].v ]=1;            if(hd[e[i].v ]==-1 || judge(hd[e[i].v ]))            {                hd[e[i].v ]=t;                return 1;            }        }    }    return 0;}int get_num(){    int num=0;    for(int i=1;i<=n;i++)    {        memset(vis,0,sizeof(vis));        if(judge(i)) num++;    }    return num;}void add(int u,int v){    e[size].v=v;    e[size].next=head[u];    head[u]=size;    size++;}bool dfs(){    memset(vis,-1,sizeof(vis));    queue<int> q;    for(int i=1;i<=n;i++)    {        if(vis[i]==-1)        {            q.push(i);            vis[i]=0;            while(!q.empty())            {                int t=q.front();                q.pop();                for(int ii=head[t];ii!=-1;ii=e[ii].next)                {                    if(vis[e[ii].v ]==-1)                    {                        if(vis[t]) vis[e[ii].v]=0;                        else vis[e[ii].v]=1;                        q.push(e[ii].v);                    }                    else if(vis[e[ii].v ]==vis[t]) return 0;                }            }        }    }    return 1;}int main(){    int p,q;    while(scanf("%d %d",&n,&m)!=EOF)    {        init();        while(m--)        {            scanf("%d %d",&p,&q);            add(p,q);            add(q,p);        }        if(!dfs()) printf("No\n");        else        {            int num=get_num();            printf("%d\n",num/2);        }    }    return 0;}


0 0