NC20483. [ZJOI2009]假期的宿舍
描述
输入描述
第一行一个数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,但是显然自己还是可以睡自己的床),
认识的关系是相互的。
1 ≤ n ≤ 50,1 ≤ T ≤ 20
输出描述
对于每组数据,如果存在一个方案则输出“^_^”(不含引号)否则输出“T_T”(不含引号)。
(注意输出的都是半角字符,即三个符号的ASCII码分别为94,84,95)
示例1
输入:
1 3 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0
输出:
^_^
C++ 解法, 执行用时: 15ms, 内存消耗: 472K, 提交时间: 2022-02-27 18:22:26
#include<bits/stdc++.h> const int N=52; using namespace std; int t,n; int a[N],b[N],w[N][N],vis[N],link[N]; int dfs(int x){ for(int i=1;i<=n;i++){ if(vis[i]||w[x][i]==0||!a[i]) continue; vis[i]=1; if(link[i]==0||dfs(link[i])){ link[i]=x; return 1; } } return 0; } void solve(){ cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<=n;i++)cin>>b[i]; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ cin>>w[i][j]; if(a[i]==1&&b[i]==0) w[i][i]=1; } memset(link,0,sizeof(link)); for(int i=1;i<=n;i++){ if(b[i]&&a[i]) continue; memset(vis,0,sizeof(vis)); if(!dfs(i)){ puts("T_T"); return; } } puts("^_^"); } int main(){ cin>>t; while(t--) solve(); return 0; }