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;
}

 

posted @ 2017-12-11 13:40  CHerish_OI  阅读(72)  评论(0编辑  收藏