bzoj1433: [ZJOI2009]假期的宿舍(最大二分图匹配)
1433: [ZJOI2009]假期的宿舍
题目:传送门
题解:
这题有点水
跑个二分图匹配就完事了(注意在校生不是一定都互相认识)
代码:
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #define qread(x)x=read(); using namespace std; inline int read() { int f=1,x=0;char ch; while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} return f*x; } int a[110][110]; int T,n,t; bool v[550]; bool b[1100][1100]; int f[550],k[1100]; int chw[11000],match[11000]; bool find_muniu(int x) { for(int i=1;i<=n;i++) { if(a[x][i] && chw[i]!=t) { chw[i]=t; if(match[i]==0 || find_muniu(match[i])) { match[i]=x; return true; } } } return false; } int main() { qread(T); while(T--) { memset(a,false,sizeof(a)); memset(chw,0,sizeof(chw)); memset(match,0,sizeof(match)); int cnt=0; qread(n); for(int i=1;i<=n;i++)qread(v[i]); for(int i=1;i<=n;i++) { qread(f[i]); if(!v[i] || (v[i] && !f[i]))//如果第i个学生不是在校生,或者是在校生但不回家,那么就需要一个床位 cnt++; } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { int x; qread(x); if(x && ((v[i] && !f[i]) || !v[i]) && v[j])a[i][j]=1; } if(v[i] && !f[i])a[i][i]=1; } int ans=0; for(int i=1;i<=n;i++) { t=i; if(find_muniu(i))ans++; } if(ans==cnt)printf("^_^\n"); else printf("T_T\n"); } return 0; }