hdu2444二分图最大匹配

来源:互联网 发布:鲸鱼宝网络不给力 编辑:程序博客网 时间:2024/05/22 02:23

先着色判断是否为二分图,同时把点分成两部分

然后用增广路算法求匹配数就ok

代码写得比较烂 31ms 比较长,用bfs着色

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <queue>#include <vector>using namespace std;vector <int> eg[205];int ex[205];int flag[205];int left1[205];queue<int>Q;int maxm;int n,m;int used[205];int judge(){    for(int i=0; i<n; i++)    {        if(!flag[i])        {            flag[i]=1;            Q.push(i);        }        else continue;        while(!Q.empty())        {            int u=Q.front();            Q.pop();            for(int i=0; i<eg[u].size(); i++)            {                int v=eg[u][i];                if(!flag[v])                {                    flag[v]=(flag[u]&1)+1;                    Q.push(v);                }                else if(flag[v]==flag[u]) return 0;            }        }    }    return 1;}int match(int cnt){    if(ex[cnt]||used[cnt]) return 0;    used[cnt]=1;    for(int i=0; i<eg[cnt].size(); i++)    {        int v=eg[cnt][i];        if(ex[v]) continue;        if(left1[v]<0||(!used[v]&&match(left1[v])))                  {                left1[v]=cnt;                return 1;        }    }    ex[cnt]=1;    return 0;}void run(){    while(scanf("%d%d",&n,&m)>0)    {        memset(flag,0,sizeof(flag));        memset(ex,0,sizeof(ex));        memset(left1,0xff,sizeof(left1));        int a,b;        for(int i=0; i<n; i++) eg[i].clear();        for(int i=0; i<m; i++)        {            scanf("%d%d",&a,&b);            eg[a-1].push_back(b-1);            eg[b-1].push_back(a-1);        }        if(judge())        {            maxm=0;            for(int i=0; i<n; i++)            {                if(flag[i]==1&&!ex[i])                {                    for(int j=0; j<n; j++) used[j]=0;                    if(match(i)) maxm++;                }            }            printf("%d\n",maxm);        }        else printf("No\n");    }}int main(){    run();    return 0;}



0 0
原创粉丝点击