HDU-2444-The Accomodation of Students(bfs染色判定是否为二分图+最大匹配)

题目

问题描述

有一群学生。他们中的一些人可能互相认识,而另一些人则不认识。例如,A和B互相认识,B和C互相认识。但这并不意味着A和C相互认识。
现在给你们所有互相认识的学生。你的任务是把学生分成两组,这样同一组的任何两个学生都不认识对方。如果这个目标可以实现,那就把他们安排在双人间。只有认识的学生才能住在同一个房间里。
计算可以安排到这些双人间的最大对数。

输入

对于每个数据集:
第一行给出两个整数n和m。接下来的m行给出这样的对。

输出

如果这些学生不能分成两组,请打印“否”。否则,打印在这些房间中可以安排的最大对。

bfs染色判定是否为二分图+最大匹配

#include <queue>
#include <cstring>
#define m(a,b) memset(a,b,sizeof a)
using namespace std;
const int N=200+5;
int head[N],mt[N];
int col[N],tot;
struct Edge{int to,nex;}edge[N*N/2];
void add(int from,int to)
{
    edge[++tot]=(Edge){to,head[from]};head[from]=tot;
}
queue<int>q;
int istwo()
{
    while(!q.empty())
        q.pop();
    m(col,0);
    col[1]=1,q.push(1);
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        for(int i=head[x];i;i=edge[i].nex)
        {
            int y=edge[i].to;
            if(!col[y])
            {
                col[y]=col[x]==1?2:1;  //相邻没被染色。染y与x不相同的颜色。
                q.push(y);
            }
            else if(col[y]==col[x])   //被染色。与相邻染色相同则不是二分图。
                return 0;
        }
    }
    return 1;
}
int find_path(int x)
{
    for(int i=head[x];i;i=edge[i].nex)
    {
        int y=edge[i].to;
        if(!col[y])
        {
            col[y]=1;
            if(!mt[y]||find_path(mt[y]))
            {
                mt[y]=x;
                return 1;
            }
        }
    }
    return 0;
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        m(head,0),m(mt,0);
        tot=1;
        while(m--)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            add(a,b);
        }
        if(!istwo())
            puts("No");
        else
        {
            int ans=0;
            for(int i=1;i<=n;i++)
            {
                m(col,0);
                if(find_path(i))
                    ans++;
            }
            printf("%d\n",ans);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_42576687/article/details/87902305
今日推荐