• bzoj1433[ZJOI2009]假期的宿舍(匈牙利)


     

    1433: [ZJOI2009]假期的宿舍

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2544  Solved: 1074

    [Submit][Status][Discuss]

    Description

    Input

    Output

    Sample Input

    1
    3
    1 1 0
    0 1 0
    0 1 1
    1 0 0
    1 0 0

    Sample Output

    ˆ ˆ

    HINT

    对于30% 的数据满足1 ≤ n ≤ 12。
    对于100% 的数据满足1 ≤ n ≤ 50,1 ≤ T ≤ 20。

     

     
    /*
    看这个题,不难发现是二分图,裸的匈牙利。 
    也很好想到要把人和床分开建图。 
    但是容易吧不在校的和在校的人分开。其实不该分开,建图是没有任何影响的
    有一点要注意,很容易忽略把在校的人和自己的床建边,忘了就WA了!
    预处理稍麻烦。 
    */ 
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 101
    
    using namespace std;
    int T,n,m,k,ans,cnt1,cnt2;
    int bed[maxn],vis[maxn],Link[maxn],Judge[maxn],people[maxn];
    int a[maxn][maxn];
    
    inline int insert()
    {
        int x=0,f=1;char c=getchar();
        while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    inline void first()
    {
        ans = 0;
        memset(a,0,sizeof(a));
        memset(bed,0,sizeof(bed));
        memset(Judge,0,sizeof(Judge));
        memset(people,0,sizeof(people));
        memset(Link,0,sizeof(Link));
        cnt1=cnt2=0;
    }
    
    bool hungarian(int x)
    {
        for(int i=1;i<=cnt1;i++)
        {
            if(a[x][bed[i]]&&!vis[bed[i]])
            {
                vis[bed[i]]=1;
                if(!Link[bed[i]]||hungarian(Link[bed[i]]))
                {
                    Link[bed[i]]=x;
                    return true;
                }
            }
        }
        return false;
    }
    
    int main()
    {
        T=insert();
        while(T--)
        {
            first();
            n=insert();
            for(int i=1;i<=n;i++)
              Judge[i]=insert();
            for(int i=1;i<=n;i++)
            {
                int tmp;
                tmp=insert();
                if(Judge[i])
                {
                    if(tmp) bed[++cnt1]=i;//不在校的 
                    else bed[++cnt1]=people[++cnt2]=i;//在校的 
                }
                else people[++cnt2]=i;//来探望的 
            }
            for(int i=1;i<=n;i++)
              for(int j=1;j<=n;j++)
                a[i][j]=insert();
            for(int i=1;i<=n;i++)
              if(Judge[i]) a[i][i]=1;//自己的床 
             for(int i=1;i<=cnt2;i++)
             {
                 memset(vis,0,sizeof(vis));
                 if(hungarian(people[i]))//if后面又打成了分号,罚自己中午多吃一个馒头2333 
                   ans++;
             } 
             if(cnt2>cnt1) ans=-1;
             if (ans == cnt2)
                printf("^_^
    ");
             else
                printf("T_T
    ");
        }
        return 0;
    }
     
    [
    折花枝,恨花枝,准拟花开人共卮,开时人去时。 怕相思,已相思,轮到相思没处辞,眉间露一丝。
  • 相关阅读:
    02基础软件安装
    01系统软件安装
    dmesg命令
    perl 远程连接oracle
    延时取消订单还在用定时任务?来看mq的实现
    微信公众号开发Java版-学习总结
    (转)SQL Server 2008 允许远程连接的解决方法
    java生成pdf并加水印,通过wkhtmltopdf实现
    boostrap-table表格插件笔记
    art-template笔记
  • 原文地址:https://www.cnblogs.com/L-Memory/p/6376930.html
Copyright © 2020-2023  润新知