bzoj1433[ZJOI2009] 假期的宿舍
题目链接:bzoj1433
题目大意:
T组数据,n个人。有些人是学校里的学生,他们在学校里就有床位。但其中有人走读,所以他们的床位到了晚上就会空出来。而有些人晚上会来拜访学校里的人,但他们没有床位。假设每个人只能睡跟他直接认识的人的床,问有没有一种分床的方案使晚上在学校的每个人都有床睡。
题解:
匈牙利求二分图最大匹配
以在校睡的人和床连边构二分图。跑最大匹配。判断一下是不是完美匹配就好了。
我只能说输出真恶心!WA了我两次QwQ样例在欺骗我!
#include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> using namespace std; #define maxn 110 struct node { int x,y,next; }a[maxn*maxn];int len,first[maxn]; int no[maxn],stu[maxn]; int bf[maxn],ask[maxn],tim; void ins(int x,int y) { len++;a[len].x=x;a[len].y=y; a[len].next=first[x];first[x]=len; } bool ffind(int x) { for (int i=first[x];i!=-1;i=a[i].next) { int y=a[i].y; if (ask[y]==tim) continue; ask[y]=tim; if (bf[y]==-1 || ffind(bf[y])) { bf[y]=x; return true; } } return false; } int main() { int T,i,n,x,sm,num,j,ans; scanf("%d",&T); while (T--) { scanf("%d",&n); num=sm=ans=tim=0; for (i=1;i<=n;i++) { scanf("%d",&x); if (x==0) no[i]=-1; else no[i]=++num; } for (i=1;i<=n;i++) { scanf("%d",&x); if (no[i]==-1) stu[i]=++sm; else if (x==0) stu[i]=++sm; else stu[i]=-1; } len=0;memset(first,-1,sizeof(first)); for (i=1;i<=n;i++) if (stu[i]!=-1 && no[i]!=-1) ins(stu[i],no[i]); for (i=1;i<=n;i++) for (j=1;j<=n;j++) { scanf("%d",&x); if (x==1 && stu[i]!=-1 && no[j]!=-1) ins(stu[i],no[j]); } memset(bf,-1,sizeof(bf)); memset(ask,0,sizeof(ask)); for (i=1;i<=n;i++) if (stu[i]!=-1) { tim++; if (ffind(stu[i])) ans++; } if (ans==sm) printf("^_^\n"); else printf("T_T\n"); } return 0; }