题面

题目描述

学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题。比如 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。

多组数据!!!

题解

观察题意

首先最简化一下

有很多很多很多人,有很多很多很多床

问你要怎么安排?

貌似太简单了额。。。

在详细的,

有很多人,若干床,

若干个人际关系

表示某人能够睡某人的床

问最后能否使得所有人都有床?

恩?

一个人对应一张床

这不就是二分图匹配?

没错,这就是二分图匹配。

但是,这要怎么建边呢?

1.如果这个人是学生,并且留在学校,自己和自己的床连线

2.如果一个人A认识另外一个人B,并且B是学生,则将A与B的床连线

建完边之后直接跑匈牙利算法

计算最大的匹配数

检查是否和要床的人数相同

最后输出即可。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<algorithm>
  7. using namespace std;
  8. const int MAX=100;
  9. const int MAXL=10000;
  10. struct Line
  11. {
  12. int v,next;
  13. }e[MAXL];
  14. int h[MAX],cnt=0,tot;
  15. int T,n;
  16. int home[MAX];
  17. int school[MAX],a,sum;
  18. inline void Add(int u,int v)
  19. {
  20. e[cnt]=(Line){v,h[u]};
  21. h[u]=cnt++;
  22. }
  23. int match[MAX];
  24. bool vis[MAX];
  25. bool DFS(int x)
  26. {
  27. for(int i=h[x];i!=-1;i=e[i].next)
  28. {
  29. int v=e[i].v;
  30. if(!vis[v])
  31. {
  32. vis[v]=true;
  33. if(!match[v]||DFS(match[v]))
  34. {
  35. match[v]=x;
  36. return true;
  37. }
  38. }
  39. }
  40. return false;
  41. }
  42. int main()
  43. {
  44. cin>>T;
  45. while(T--)
  46. {
  47. cnt=tot=0;
  48. memset(h,-1,sizeof(h));
  49. cin>>n;
  50. for(int i=1;i<=n;++i)
  51. cin>>school[i];
  52. for(int i=1;i<=n;++i)
  53. {
  54. cin>>home[i];
  55. if(home[i]==0&&school[i])//如果此人是在校学生并且不回家
  56. Add(i,i);//可以睡自己的床
  57. }
  58. for(int i=1;i<=n;++i)//统计要床的人
  59. if(!school[i]||(school[i]&&!home[i]))
  60. ++tot;
  61. for(int i=1;i<=n;++i)
  62. {
  63. for(int j=1;j<=n;++j)
  64. {
  65. cin>>a;
  66. if(a&&school[j])//如果i认识j并且j是学生
  67. Add(i,j);//i可以睡j的床
  68. }
  69. }
  70. memset(match,0,sizeof(match));
  71. sum=0;
  72. for(int i=1;i<=n;++i)
  73. {
  74. if((school[i]&&home[i]==0)||!school[i])//要么是学生在学校,要么是外来的人
  75. {
  76. memset(vis,0,sizeof(vis));
  77. if(DFS(i))++sum;
  78. }
  79. }
  80. if(sum==tot)
  81. cout<<"^_^"<<endl;
  82. else
  83. cout<<"T_T"<<endl;
  84. }
  85. return 0;
  86. }

【洛谷2055】【CJOJ2487】【ZJOI2009】 假期的宿舍的更多相关文章

  1. 洛谷 P2055 [ ZJOI 2009 ] 假期的宿舍 —— 二分图匹配

    题目:https://www.luogu.org/problemnew/show/P2055 二分图匹配: 注意要连边的话对方必须有床! 代码如下: #include<iostream> ...

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

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

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

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

  4. 2055 [ZJOI2009]假期的宿舍

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

  5. BZOJ1433 ZJOI2009 假期的宿舍 二分图匹配

    1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2375  Solved: 1005[Submit][Sta ...

  6. bzoj1433: [ZJOI2009]假期的宿舍

    1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2286  Solved: 969[Submit][Stat ...

  7. bzoj1433:[ZJOI2009]假期的宿舍

    明显的二分图最大匹配. #include<cstdio> #include<cstring> #include<cctype> #include<algori ...

  8. bzoj1433 [ZJOI2009]假期的宿舍(最大流)

    1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1717  Solved: 754[Submit][Stat ...

  9. BZOJ_1433_[ZJOI2009]假期的宿舍_二分图匹配

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

  10. 1433: [ZJOI2009]假期的宿舍

    1433: [ZJOI2009]假期的宿舍 链接 分析: 直接网络流,看是否满足即可. S向每个有需要的人连边,有床的向T连边,认识的人之间互相连边. 代码: #include<cstdio&g ...

随机推荐

  1. javascript 模块

    一.模块 function foo() { var something = "cool"; var another = [1, 2, 3]; function doSomethin ...

  2. 洛谷P2832 行路难 分析+题解代码【玄学最短路】

    洛谷P2832 行路难 分析+题解代码[玄学最短路] 题目背景: 小X来到了山区,领略山林之乐.在他乐以忘忧之时,他突然发现,开学迫在眉睫 题目描述: 山区有n座山.山之间有m条羊肠小道,每条连接两座 ...

  3. Apache和Tomcat的区别与联系

    作者:郭无心链接:https://www.zhihu.com/question/37155807/answer/72706896来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...

  4. C语言_结构体的4种定义初始化方式及案例

    结构体是一种构造数据类型 (构造数据类型:数组类型.结构体类型(struct).共用体类型(union)).用途:把不同类型的数据组合成一个整体,通俗讲就像是打包封装,把一些有共同特征(比如同属于某一 ...

  5. nyoj49 开心的小明 01背包

    思路:dp(i, j)表示用金钱j去买前i个物品能得到的最大价值.转移方程dp(i, j) = max{dp(i-1, j), dp(i-1, j-p[i]) + p[i]*w[i]}. AC代码 # ...

  6. uva140

    全排列回溯剪枝. 题目数据很水.记录当前最小带宽,边回溯边计算当前序列最大的距离(也就是带宽),如果当前带宽超过了当前的最小带宽就剪枝. 注意下,数据读入时的字符串处理. AC代码 #include& ...

  7. uva1471 二叉搜索树

    此题紫书上面有详细分析,关键是运用Set优化实现O(nlgn)复杂度 AC代码: #include<cstdio> #include<set> #include<algo ...

  8. logback KafkaAppender 写入Kafka队列,集中日志输出.

    为了减少应用服务器对磁盘的读写,以及可以集中日志在一台机器上,方便使用ELK收集日志信息,所以考虑做一个jar包,让应用集中输出日志 网上搜了一圈,只发现有人写了个程序在github 地址:https ...

  9. ubuntu14.04 安装redis 2.8.9

    ubuntu14.04安装前准备工作,为了保证安装顺利,请先执行apt-get update 然后安装make 和gcc(已安装的可忽略) apt-get install make apt-get i ...

  10. Hive分区和桶

    SMB 存在的目的主要是为了解决大表与大表间的 Join 问题,分桶其实就是把大表化成了“小表”,然后 Map-Side Join 解决之,这是典型的分而治之的思想.在聊 SMB Join 之前,我们 ...