luogu2055 [ZJOI2009]假期的宿舍

本篇博文解析洛谷平台题目2055,采用最大流算法解决学生住宿分配问题。通过建立网络流模型,连接源点到学生及床位到汇点,判断是否能恰好满足所有学生的住宿需求。

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

题目

  https://www.luogu.org/problem/show?pid=2055

题解

  题目很简单就是有点绕。。

  读懂了题大概就会做了,让i表示i这个人,N+i表示这个人的床。如果i认识j且j是在校生,就连一条i->N+j的边,容量为1;然后每个需要在学校睡觉的人从S连向它,容量为1;每张床连向T,容量为1,统计一下有多少人需要在学校睡觉,再看看和最大流是不是相等就行了。

代码

//最大流 
#include <cstdio>
#include <algorithm>
#include <cstring>
#define maxn 100000
using namespace std;
int N, cases, next[maxn], head[maxn], tot=1, to[maxn], c[maxn], d[maxn], num[maxn],
	Exit, last[maxn], S, T, rl[100][100], inschool[maxn], gohome[maxn], cnt;
void adde(int a, int b, int v){to[++tot]=b;c[tot]=v;next[tot]=head[a];head[a]=tot;}
void adde2(int a, int b, int v){adde(a,b,v);adde(b,a,0);}
int ISAP(int pos, int in)
{
	int t, p, flow=0;
	if(pos==T)return in;
	for(p=last[pos];p;last[pos]=p=next[p])
		if(c[p] and d[pos]==d[to[p]]+1)
		{
			flow+= t=ISAP(to[p],min(in-flow,c[p]));
			c[p]-=t, c[p xor 1]+=t;
			if(Exit or in==flow)return flow;
		}
	Exit = --num[d[pos]]==0;
	++num[++d[pos]];
	last[pos]=head[pos];
	return flow;
}
void init()
{
	memset(head,0,sizeof(head));
	memset(next,0,sizeof(next));
	memset(last,0,sizeof(last));
	memset(d,0,sizeof(d));
	memset(num,0,sizeof(num));
	memset(rl,0,sizeof(rl));
	tot=1, Exit=0, cnt=0;
	int i, j, x;
	scanf("%d",&N);
	S=N+N+1, T=S+1;
	for(i=1;i<=N;i++)scanf("%d",inschool+i);
	for(i=1;i<=N;i++)scanf("%d",gohome+i);
	for(i=1;i<=N;i++)for(j=1;j<=N;j++)
	{
		scanf("%d",&x);
		if((x and inschool[j]) or i==j)adde2(i,N+j,1);
	}
	for(i=1;i<=N;i++)
	{
		if(!(inschool[i] and gohome[i]))adde2(S,i,1),cnt++;
		if(inschool[i])adde2(N+i,T,1);
	}
}
int main()
{
	int flow;
	scanf("%d",&cases);
	while(cases--)
	{
		init();
		flow=0;
		while(!Exit)flow+=ISAP(S,0x7fffffff);
		if(flow==cnt)printf("^_^\n");else printf("T_T\n");
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值