HDU 2444 判断二分图+最大匹配

来源:互联网 发布:泗阳网络问政123456 编辑:程序博客网 时间:2024/05/19 23:00
//题意概述:给出一些人的关系,A认识B,B认识C,不代表A认识C,有一些双人房间,要求要相互认识的才能分进同一间,问能最多需要多少间房//题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2444//先判断是否是二分图,不是直接输出NO,是则进行求最大匹配#include <iostream>#include <queue>#include <vector>using namespace std;const int Nocolor = 0;const int White = 1;const int Black = 2;const int MAXN = 210;int color[MAXN]; vector<int>V[MAXN];bool used[MAXN];int link[MAXN];       int n;//染色法bool judge(int start){    queue<int>Q;    Q.push(start);    color[start] = White;  //初始化源点为白色    while(!Q.empty())    {        int now = Q.front();        Q.pop();        for(int i=0; i<V[now].size(); i++)  //采用邻接表存图        {            int temp = V[now][i];               if(color[temp] == Nocolor)              {                if(color[now] == White)                {                    color[temp] = Black;                }                else if(color[now] == Black)                {                    color[temp] = White;                }                Q.push(temp);            }            if(color[temp] == color[now])              {                return false;            }        }    }    return true;}//匈牙利bool findPath(int u){          int size = V[u].size();          for(int i=0; i<size; i++)          {              int v = V[u][i];                if(!used[v])              {                  used[v] = true;                  if(link[v] == -1 || findPath(link[v])) //找到未匹配的边                  {                      link[v] = u;                        return true;                  }              }          }          return false;}int solve(){    int Count = 0;    memset(link,-1,sizeof(link));    for(int i=1; i<=n; i++)      {        memset(used,0,sizeof(used));         if(findPath(i))        {            Count++;        }    }    return Count; }int main(){    int m;    int a,b;    int flag;  //记录是否矛盾    while(cin>>n>>m)    {        //记得初始化        for(int i=1; i<=n; i++)        {            V[i].clear();        }        memset(color, 0, sizeof(color));        while(m--)        {            cin>>a>>b;            //无向图            V[a].push_back(b);            V[b].push_back(a);        }        flag = 1;        for(i=1; i<=n; i++)        {            if(color[i] == Nocolor && !judge(i))             {                flag = 0;                break;            }        }        if(flag)        {            int ans = solve();//最大匹配数            cout<<ans/2<<endl;        }        else            cout<<"No"<<endl;//不是二分图    }    return 0;}