文理分班[二分图]
文理分班[二分图]
题目描述
jzyz每年的文理分班的时候,每个班都会有一些同学分到其他班,还会进入一些其他班的同学进入这个班。
小x负责安排座位,为了照顾分班带来的那种伤感情绪,小x制定了很人性化的座位安排计划,具体计划如下:
比如A和B都是本班学生且是好朋友,A分到了其他班,而C则是外班进入这个班的,C和A并不熟悉,而C和B关系很好,那么小x为了照顾A和C的情绪,就会让B坐在A的位置,C坐在B的位置。
当然,实际情况可能很复杂,比如一个班里的同学之间关系不一定好,外班进来的可能和本班很多人关系都很好。
现在告诉你,和小x所在班有关系的人一共有n个人,小x想知道有没有一个合理的方案来满足自己的座位安排计划。
输入格式
本题为多组数据,第一行一个整数M,表示有M组测试数据。
对于每组测试数据,每组的第一行一个整数n,表示一共有n个人和这个班有关系。
接下来一行n个整数,第i个整数表示第i个人是否是本班学生(0表示不是,1表示是,分到其他班的也算是本班学生)
接下来一行n个整数,第i个整数表示第i个人是否要分到其他班(0表示留在本班,1表示分到其他班,如果第i个人是由外班分进来的,那么第i个整数就是一个随机整数,没有实际意义)
接下来是一个n行n列的一个二维矩阵,第i行第j列的数表示第i个人和第j个人是否关系很好(1表示认识,0表示不认识),对角线上是0,但是自己肯定认识自己。
输出格式
每组数据,如果存在一个方案,输出 “_”(不含引号)。
如果没有方案,输出 “T_T”(不含引号)。都是半角字符。
样例
样例输入
1
3
1 1 0
0 1 0
0 1 1
1 0 0
1 0 0
样例输出
^_^
思路
首先diss出题人, 把话说清楚能死? 阅读理解也没宁这么出的
"n个人和这个班有关系。" 在这的意思是, 不是本班的学生一定会分来本班, 因为他和这个班有联系
小x要管的人, 只包括本班教室里的人 (没有被分走的本班学生和分进来的外班学生)
明确了题意,我们来解释一下样例的3,4行
1 1 0
0 1 0
第一个人:是本班学生, 没有分走
第二个人:是本班学生,但被分到了外班
第三个人:不是本班学生, 一定会分来本班, 第二行的 0 只是一个随机整数, 而不是代表他留在自己的班
好了!只要你搞清楚题意, 这道题就是个板子 (出题人我谢谢宁全家)
考虑一下哪些人可以相互换坐
- 自己是本班学生, 没被分走, 自己可以坐在自己的座位上(和自己换坐)
- 某个人和本班的一个学生是朋友, 他们两个就可以换坐(即使本班的这个学生被分走, 他的座位还留在本班教室)
对小x需要管的人跑一边匈牙利, 如果一个人找不到可以换坐的, 就可以直接break了
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 1050;
int n, k, m, vis[maxn], match[maxn], ans, g[maxn][maxn], a[maxn], b[maxn];
int find(int u){//匈牙利
for(int i=1; i<=n; i++){
if(g[u][i] && !vis[i]){
vis[i] = 1;
if(!match[i] || find(match[i])){
match[i] = u;
return 1;
}
}
}
return 0;
}
int main(){
scanf("%d", &m);
while(m--){
memset(g, 0, sizeof(g));
memset(match, 0, sizeof(match));//记得初始化
scanf("%d", &n);
for(int i=1; i<=n; i++) scanf("%d", &a[i]);//是否为本班学生
for(int i=1; i<=n; i++){
scanf("%d", &b[i]);//是否分走
if(a[i]==1 && b[i]==0) g[i][i] = 1;//是本班学生且没被分走,自己可以和自己换坐
}
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
int x; scanf("%d", &x);
if(x==1 && a[j]==1) g[i][j] = 1;//i和j很熟, 且j是本班的(即使j被分到外班,j的座位还在本班)
}
}
bool flag = 0;
for(int i=1; i<=n; i++){
memset(vis,0,sizeof(vis));
if((!a[i]) || (a[i]&&!b[i])){//没有被分走的本班学生和分进来的外班学生
if(!find(i)){//找不到可以换坐的人
flag=1;
break;
}
}
}
printf("%s\n", flag ? "T_T" : "^_^");
}
return 0;
}

浙公网安备 33010602011771号