洛谷P2055 [ZJOI2009]假期的宿舍 二分图 匈牙利算法

题目链接:https://www.luogu.com.cn/problem/P2055

本题可以用二分图匹配很好的解决,我们这里是人找床,如果两个人 A 和 B 认识,并且 B 是学校里的学生,那么 A 就可以睡 B 的床,当然 A 也可以睡自己的床。之后用匈牙利算法,找二分图匹配即可。
代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=55;
const int maxm=2505;
int gohome[maxn];//是否回家
int school[maxn];//是否是学校里的学生
int line[maxn][maxn];//人与人是否认识
bool used[maxn];//是否尝试过改变
int bed[maxn];//该床被谁占用
int n,T;
bool find(int x)//二分图匹配
{
    for(int i=1;i<=n;i++)
    {
        if(line[x][i]&&!used[i])//如果可以选这张床且未做过改变
        {
            used[i]=true;
            if(!bed[i]||find(bed[i]))//未被占用或者可以换
            {
                bed[i]=x;
                return true;
            }
        }
    }
    return false;
}
int main()
{
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            bool flag=false;
            for(int i=1;i<=n;i++)
            scanf("%d",&school[i]),bed[i]=0;
            for(int i=1;i<=n;i++)
            scanf("%d",&gohome[i]);
            for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                scanf("%d",&line[i][j]);
                if(!school[j])//不是学校学生没有床
                {
                    line[i][j]=0;
                    continue;
                }
                if(i==j)//每个人可以睡自己床
                {
                    line[i][j]=1;
                    continue;
                }
            }
            for(int i=1;i<=n;i++)
            {
                memset(used,0,sizeof(used));
                if(!school[i]||!gohome[i])
                {
                    if(!find(i))
                    {
                        puts("T_T");
                        flag=true;
                        break;
                    }
                }
            }
            if(!flag)
            puts("^_^");
        }
    return 0;
}
上一篇:[ZJOI2009] 硬币游戏


下一篇:洛谷P1434 [SHOI2002]滑雪