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("^_^
");
        else         printf("T_T
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/AKCqhzdy/p/7859814.html