主要是main()中的处理,接下来就是二分匹配的模板题了
#include<cstdio> #include<cstring> #define maxn 110 using namespace std; int a[maxn][maxn],link[maxn]; int b[maxn],c[maxn]; bool vis[maxn]; int n,m,cnt,ans,T; bool find(int x) { for(int j=1;j<=n;j++){ if(a[x][j]&&!vis[j]){ vis[j]=1;//为了下一条语句中调用find做准备的,以免重复 if(!link[j]||find(link[j])){ link[j]=x; return 1; } } } return 0; } int main() { scanf("%d",&T); while (T--){ memset(a,0,sizeof(a)); memset(link,0,sizeof(link)); scanf("%d",&n); cnt=ans=0; for(int i=1;i<=n;i++) scanf("%d",&b[i]); for(int i=1;i<=n;i++){ scanf("%d",&c[i]); if(!b[i]||(b[i]&&!c[i])) cnt++; }//cnt表示需要床位的学生人数 for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ int x; scanf("%d",&x);//i是本校生而且不回家或者i不是本校生但是i认识本校生j,j回不回家i都有可能睡j的床 if(x&&((b[i]&&!c[i])||!b[i])&&b[j]) a[i][j]=1;//a[i][j]=1表示i可以睡j的床 } if(b[i]&&!c[i])//自己是本校生而且自己不回家,那么自己可以睡自己的床 a[i][i]=1; } for(int i=1;i<=n;i++){ memset(vis,0,sizeof(vis)); if(find(i)) ans++; } if(ans==cnt) printf("^_^ "); else printf("T_T "); } return 0; }