bzoj1433: [ZJOI2009]假期的宿舍
一道匈牙利的裸题,将床和人建边,纯属复习模版了(然而就是写错了)
注意一下0和1的表示。
#include<cstdio> #include<cstring> using namespace std; struct node { int x,y,next; }a[41000];int len,last[2100]; void ins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; } int match[2100]; bool v[2100]; bool find_muniu(int x) { for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(v[y]==false) { v[y]=true; if(match[y]==0||find_muniu(match[y])==true) { match[y]=x; return true; } } } return false; } int z[1100],l[1100],ysp[1100],ysb[1100]; int main() { freopen("holiday.in","r",stdin); freopen("holiday.out","w",stdout); int T; scanf("%d",&T); while(T--) { int n,P=0,B=0; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&z[i]); if(z[i]==1)ysb[i]=++B; } for(int i=1;i<=n;i++) { scanf("%d",&l[i]); if(z[i]==0)l[i]=0; if(l[i]==0)ysp[i]=++P; } int x;//1~P表示人,P+1~B表示床 len=0;memset(last,0,sizeof(last)); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { scanf("%d",&x); if(l[i]==1||z[j]==0)continue; if(i==j||x==1) { ins(ysp[i],ysb[j]); } } memset(match,0,sizeof(match)); bool bk=true; for(int i=1;i<=P;i++) { memset(v,false,sizeof(v)); if(find_muniu(i)==false){bk=false;break;} } if(bk==true)printf("^_^\n"); else printf("T_T\n"); } return 0; }
pain and happy in the cruel world.