题目描述

学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题。

比如 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。

多组数据!!!

思路

  把人和床位分成两个不同的点集来看,要求最大的匹配数量问是否等于 留校人数 + 外来人员数量。

  显然跑最大流和二分匹配都是可以的。

CODE

 #include <bits/stdc++.h>

 using namespace std;
const int maxn = ; int n,m,e, tot, sum;
int vis[maxn];
int ask[maxn];
int ans;
int inschool[maxn];
int matched[maxn];
int gohome[maxn];
int head[], edge[], nxt[], cnt; void BuildGraph(int u, int v) {
cnt++;
edge[cnt] = v;
nxt[cnt] = head[u];
head[u] = cnt;
} bool fid(int x) {
for(int i = head[x]; i; i = nxt[i]) {
int v = edge[i];
if(!vis[v]) {
vis[v] = ;
if(!matched[v] || fid(matched[v])) {
matched[v] = x;
return true;
}
}
}
return false;
} void match() {
sum = ;
memset(matched, , sizeof(matched));
for(int i = ; i <= n; ++i) {
if((inschool[i] && !gohome[i]) || !inschool[i]) {
memset(vis, , sizeof(vis));
if(fid(i)) {
sum++;
}
}
}
} int main()
{ int t;
cin >> t;
while(t--) {
scanf("%d",&n);
cnt = , tot = , sum = ;
memset(edge, , sizeof(edge));
memset(vis, , sizeof(vis));
memset(head, , sizeof(head));
memset(inschool, , sizeof(inschool));
memset(gohome, , sizeof(gohome));
memset(nxt, , sizeof(nxt));
for ( int i = ; i <= n; ++i ) {
scanf("%d",&inschool[i]);
}
for ( int i = ; i <= n; ++i ) {
scanf("%d",&gohome[i]);
if(!gohome[i] && inschool[i]) {
BuildGraph(i, i);
}
}
for ( int i = ; i <= n; ++i ) {
if(!inschool[i] || (inschool[i] && !gohome[i])) {
++tot;
}
}
for ( int i = ; i <= n; ++i ) {
for ( int j = ; j <= n; ++j ) {
int x;
scanf("%d",&x);
if(x && inschool[j]) {
BuildGraph(i, j);
}
}
}
match();
if(tot == sum) puts("^_^");
else {
puts("T_T");
}
//printf("tot:%d sum:%d\n",tot,sum);
}
return ;
}

最新文章

  1. NVMe over Fabrics又让RDMA技术火了一把
  2. Spring整合jdbc
  3. Javascript为元素添加事件处理函数
  4. jsp 微信公众平台 token验证(php、jsp)(转载)
  5. 用Meta标签控制360浏览器默认极速模式打开自己的网站和正则表达式
  6. (转)理解SQL SERVER中的分区表
  7. Dijkstra算法and Floyd算法 HDU 1874 畅通工程续
  8. 命运(HDU 2571 简单动态规划)
  9. 【转载】HTML和XML的区别
  10. Unity发布至IOS的流程(踩坑记录)
  11. linux常见基本命令
  12. 高斯-克吕格投影与UTM投影
  13. New text file line delimiter
  14. Effective OC : 1-5
  15. jdbc链接数据库,获取表名,字段名和数据
  16. ubuntu 14.04 安装boost 1.53
  17. bzoj3663/4660CrazyRabbit &amp;&amp; bzoj4206最大团
  18. Python面试题目之(针对dict或者set数据类型)边遍历 边修改 报错dictionary changed size during iteration
  19. Saltstack sls文件:批量替换指定文件
  20. ls存在的文件,不能操作

热门文章

  1. 实验3: DHCP 基本配置
  2. 《 Java 编程思想》CH02 一切都是对象
  3. java上传组件commons-fileupload的一些使用方法
  4. 【VC++开发实战】迅雷晒密及批量查询流量程序
  5. python笔记18(复习)
  6. 【限时免费】近1000G JAVA学习视频下载
  7. 带大家用40行python代码实现一个疫情地图
  8. os.path.join() - 忽略绝对路径前的参数
  9. [redis读书笔记] 第一部分 数据结构与对象 对象类型
  10. debian 安装xz 命令