bzoj1433: [ZJOI2009]假期的宿舍(二分图匹配)

本文介绍了一种解决特定住宿分配问题的方法,通过使用二分图匹配算法来确定最佳的学生床位分配方案。针对在校学生之间可能存在的床位共享情况,文章详细阐述了如何构造二分图并运行最大匹配算法,最终实现所有床位的有效利用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目传送门
有点恶心。

解法:
二分图匹配直接上。
如果你在校而且不回家,那么自己可以睡自己的床。
如果你认识的人在校,那么你可以睡他的床。
跑一遍最大匹配。。

话说题目描述好像有点问题吧。。
怎么A和B是在校学生B就可以睡A的床了。。
搞得我一开始以为在校的都互相认识。
WA无限。

代码实现:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
struct node {int x,y,next;}a[110000];int len,last[11000];
void ins(int x,int y) {len++;a[len].x=x;a[len].y=y;a[len].next=last[x];last[x]=len;}
int t,chw[11000],match[11000];
bool findmuniu(int x) {
    for(int k=last[x];k;k=a[k].next) {
        int y=a[k].y;
        if(chw[y]!=t) {
            chw[y]=t;if(match[y]==0||findmuniu(match[y])==true) {match[y]=x;return true;}
        }
    }return false;
}
int v[110],s[110];//v在校,s回家 
int main() {
    int T;scanf("%d",&T);
    while(T--) {
        int n;scanf("%d",&n);len=0;memset(last,0,sizeof(last));
        for(int i=1;i<=n;i++)scanf("%d",&v[i]); 
        for(int i=1;i<=n;i++)scanf("%d",&s[i]);
        for(int i=1;i<=n;i++)if(v[i]==1&&s[i]==0)ins(i,i);
        int cnt=0;for(int i=1;i<=n;i++)if(v[i]==0||(v[i]==1&&s[i]==0))cnt++;
        for(int i=1;i<=n;i++)for(int j=1;j<=n;j++) {
            int x;scanf("%d",&x);
            if(x==1&&(v[i]==0||(v[i]==1&&s[i]==0))&&v[j]==1)ins(i,j);
        }
        bool bk=true;memset(match,0,sizeof(match));memset(chw,0,sizeof(chw));t=0;int ans=0;
        for(int i=1;i<=n;i++) {
            t++;if(findmuniu(i)==true)ans++;
        }
        if(ans==cnt)printf("^_^\n");
        else printf("T_T\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值