洛谷 P2055

题目描述

学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题。比如 A 和 B 都是学校的学生,A 要回家,而 C 来看B,C 与 A 不认识。我们假设每个人只能睡和自己直接认识的人的床。那么一个解决方案就是 B 睡 A 的床而 C 睡 B 的床。而实际情况可能非常复杂,有的人可能认识好多在校学生,在校学生之间也不一定都互相认识。我们已知一共有 n 个人,并且知道其中每个人是不是本校学生,也知道每个本校学生是否回家。问是否存在一个方案使得所有不回家的本校学生和来看他们的其他人都有地方住。

输入输出格式

输入格式:

第一行一个数 T 表示数据组数。接下来 T 组数据,每组数据第一行一个数n 表示涉及到的总人数。接下来一行 n 个数,第 i
个数表示第 i 个人是否是在校学生 (0 表示不是,1 表示是)。再接下来一行 n 个数,第 i 个数表示第 i 个人是否回家 (0
表示不会家,1 表示回家,注意如果第 i 个人不是在校学生,那么这个位置上的数是一个随机的数,你应该在读入以后忽略它)。接下来 n 行每行 n
个数,第 i 行第 j 个数表示 i 和 j 是否认识 (1 表示认识,0 表示不认识,第 i 行 i 个的值为
0,但是显然自己还是可以睡自己的床),认识的关系是相互的。

输出格式:

对于每组数据,如果存在一个方案则输出 “ ^_^ ”(不含引号) 否则输出“T_T”(不含引号)。(注意输出的都是半角字符,即三个符号的 ASCII 码分别为94,84,95)

输入输出样例

输入样例#1:

1
3
1 1 0
0 1 0
0 1 1
1 0 0
1 0 0
输出样例#1:

^_^

说明

对于 30% 的数据满足 1 ≤ n ≤ 12。

对于 100% 的数据满足 1 ≤ n ≤ 50,1 ≤ T ≤ 20。

多组数据!!!

Solution:

这道题一看就类似于二分图匹配的问题,既可以用匈牙利算法来做也可以用最大流做。

1、用匈牙利算法。思路就是把每个是学校里的学生和他们自己的床位相连且边权为1(实际实现时可以都连,只需要在增广时判断就行了),再统计需要在学校住的同学的人数(因为只有这些人需要床位),然后把相互认识的人和床位相连且边权为1(实际实现时这里也可以不必判断是否是学校的学生,只需要增广时特判就行了)。。。关键的增广时,记得判断:必须是留在学校的学生或者外来的学生,才能以他为起点进行增广。最后若增广累加的值等于一开始统计的需要在学校住的人数,则可以,否则不行。

代码:

 #include<bits/stdc++.h>
#define il inline
using namespace std;
const int N=,inf=;
int T,n,l[N],k[N],cnt,pre[N],ans,tot,h[N];
bool vis[N];
struct edge{
int to,net;
}e[N*];
il void add(int u,int v)
{
e[++cnt].to=v,e[cnt].net=h[u],h[u]=cnt;
}
il bool find(int u)
{
for(int i=h[u];i;i=e[i].net){
int v=e[i].to;
if(!vis[v]){
vis[v]=;
if(!pre[v]||find(pre[v])){pre[v]=u;return ;}
}
}
return ;
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
ans=tot=;cnt=;
memset(h,,sizeof(h));
memset(pre,,sizeof(pre));
for(int i=;i<=n;i++)scanf("%d",&l[i]);
for(int i=;i<=n;i++){
scanf("%d",&k[i]);
if(l[i]&&!k[i])add(i,i+n);
}
for(int i=;i<=n;i++)
if(!l[i]||(l[i]&&!k[i]))tot++;
int x;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++){
scanf("%d",&x);
if(x&&l[j])add(i,j+n);
}
for(int i=;i<=n;i++)
if(!l[i]||(l[i]&&!k[i])){
memset(vis,,sizeof(vis));
if(find(i))ans++;}
// printf("%d %d\n",ans,tot);
if(ans==tot)printf("^_^\n");
else printf("T_T\n");
}
return ;
}

2、用最大流做。思路与匈牙利算法的类似,但是附加源点S(连向需要住校的人并赋权值为1)和汇点T(由每个床位连向T并赋权值为1),然后与匈牙利算法相同,统计需要住校的人数,加边时注意必须是需要住校的且认识的才能与床位相连(该回家的肯定是回家好,这样不占床位),最后增广累加答案,若等于需要住校的人数则可以,否则不行。

代码:

 #include<bits/stdc++.h>
#define il inline
using namespace std;
const int N=,inf=;
int T,n,s,t=,l[N],k[N],cnt=,dis[N],h[N],ans,tot;
queue<int>q;
struct edge{
int to,net,v;
}e[N*];
il void add(int u,int v,int w)
{
e[++cnt].to=v,e[cnt].v=w,e[cnt].net=h[u],h[u]=cnt;
e[++cnt].to=u,e[cnt].v=,e[cnt].net=h[v],h[v]=cnt;
}
il bool bfs()
{
memset(dis,-,sizeof(dis));
q.push(s),dis[s]=;
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=h[u];i;i=e[i].net)
if(dis[e[i].to]==-&&e[i].v>)dis[e[i].to]=dis[u]+,q.push(e[i].to);
}
return dis[t]!=-;
}
il int dfs(int u,int op)
{
if(u==t)return op;
int flow=,used=;
for(int i=h[u];i;i=e[i].net)
{
int v=e[i].to;
if(dis[v]==dis[u]+&&e[i].v>)
{
used=dfs(v,min(op,e[i].v));
if(!used)continue;
flow+=used,op-=used;
e[i].v-=used,e[i^].v+=used;
if(!op)break;
}
}
if(!flow)dis[u]==-;
return flow;
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=;i<=N;i++)h[i]=,l[i]=,k[i]=;
//memset(e,0,sizeof(e));
cnt=;ans=tot=;
int x;
for(int i=;i<=n;i++)scanf("%d",&l[i]);
for(int i=;i<=n;i++){
scanf("%d",&x);
if(l[i]==)k[i]=x;
}
for(int i=;i<=n;i++){
if(!k[i])add(s,i,),tot++;
if(l[i])add(i+n,t,);
}
for(int i=;i<=n;i++)
for(int j=;j<=n;j++){
scanf("%d",&x);
if(x==||i==j)add(i,j+n,);
}
while(bfs())ans+=dfs(s,inf);
if(ans==tot)printf("^_^\n");
else printf("T_T\n");
}
return ;
}

洛谷 P2055 [ZJOI2009]假期的宿舍的更多相关文章

  1. 洛谷P2055 [ZJOI2009]假期的宿舍

    P2055 [ZJOI2009]假期的宿舍 题目描述 学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题.比如 A 和 B 都是学校的学生,A ...

  2. 洛谷——P2055 [ZJOI2009]假期的宿舍

    P2055 [ZJOI2009]假期的宿舍 学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题.比如 A 和 B 都是学校的学生,A 要回家,而 ...

  3. 洛谷P2055 [ZJOI2009]假期的宿舍 题解

    题目链接: https://www.luogu.org/problemnew/show/P2055 分析: 这道题比较简单,二分图的练习题(当然最大流同理). 易得我们可以将人放在一侧,床放在一侧. ...

  4. 洛谷P2055 [ZJOI2009]假期的宿舍 [二分图最大匹配]

    题目描述 学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题.比如 A 和 B 都是学校的学生,A 要回家,而 C 来看B,C 与 A 不认识. ...

  5. 洛谷$P2055\ [ZJOI2009]$ 假期的宿舍 最大流

    正解:最大流 解题报告: 传送门$QwQ$ 这种一看就很网络流鸭,直接说咋建图趴. 考虑把在校的人拆成人和床.$S$连向所有不回家的人,所有床连向$T$,认识的人之间人向床连边,跑个最大流就成. $o ...

  6. 洛谷 P2055 【假期的宿舍】

    题库 :洛谷 题号 :2055 题目 :假期的宿舍 link :https://www.luogu.org/problem/P2055 首先明确一下:校内的每个学生都有一张床(只是校内的有) 思路 : ...

  7. BZOJ1433或洛谷2055 [ZJOI2009]假期的宿舍

    BZOJ原题链接 洛谷原题链接 对于每个需要床位的人向他能睡的床连边,然后就是二分图最大匹配模板了. 这里用匈牙利算法. #include<cstdio> #include<cstr ...

  8. 洛谷2055 [ZJOI2009]假期的宿舍

    题目描述 学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题.比如 A 和 B 都是学校的学生,A 要回家,而 C 来看B,C 与 A 不认识. ...

  9. 洛谷 2055 [ZJOI2009]假期的宿舍——二分图匹配

    题目:https://www.luogu.org/problemnew/show/P2055 #include<iostream> #include<cstdio> #incl ...

随机推荐

  1. python 多线程笔记(1)-- 概念

    本文对不使用线程和使用线程做了一个对比. 假设有两件事情:听歌.看电影 一.不用线程 import time songs = ['爱情买卖','朋友','回家过年','好日子'] movies = [ ...

  2. NIS - 深入了解如何搭建NIS环境

    第一篇[NIS]深入了解NIS 1     环境准备 操作系统:CentOS7.2 服务端安装如下软件: 软件名称 功能 ypserv NIS Server端的服务进程 rpcbind 提供RPC服务 ...

  3. day 12 文件操作

    1.文件定位读写  f.seek(2,0) ##### f.seek(2,0) In [4]: f = open("test.py","r") In [5]: ...

  4. C#:通过NuGet程序包下载CefSharp来加载谷歌浏览器

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 首先我讲明一下我要做的,公司有个C# wpf的项目需要我把一个开发好的网页嵌入到客户端当中,由于种种原因,我放 ...

  5. Maven学习(十三)-----Maven 构建生命周期

    Maven 构建生命周期 构建生命周期是什么? 构建生命周期阶段的目标是执行顺序是一个良好定义的序列. 这里使用一个例子,一个典型的 Maven 构建生命周期是由下列顺序的阶段: 阶段 处理 描述 准 ...

  6. 订单号生成逻辑,C#和JAVA双版

    五年没写过博客了,倒是天天在看 转来转去,又转回技术 原来一直在使用微软爸爸的东西,最近一两年开始玩android,玩java,还有PostgreSQL 都有些应用了,倒是可以整理些随笔出来,这就是其 ...

  7. Windows隐藏账户

    win7系统用户由于共享文件,会开启Guest来宾帐户,开启Guest来宾帐户后发现登录界面会显示guest帐户,但是只有在有密码的情况下才会显示,很多用户不喜欢显示guest帐户,那么Win7登录界 ...

  8. java面向对象的冒泡排序,选择排序和插入排序的比较

    这三种排序有俩个过程: 1.比较俩个数据. 2.交换俩个数据或复制其中一项. 这三种排序的时间级别 冒泡排序:比较 (N-1)+(N-2)+...+2+1 = N*(N-1)/2=N2/2 交换  0 ...

  9. UI分析之石家庄铁道大学官网

    点击进入石家庄铁道大学的官方网站,首先映入眼帘的是“石家庄铁道大学”七个大字,配以蓝色背景和学校的俯瞰图,给人一种严谨又不失清新的感觉. 学校的网站首页界面主要有九个界面,分别是网站首页,学校概况,组 ...

  10. Jquery mobile div常用属性

    组件 页面 jQuery Mobile 应用了 HTML5 标准的特性,在结构化的页面中完整的页面结构分为 header. content.footer 这三个主要区域. 在 body 中插入内容块: ...