zoukankan      html  css  js  c++  java
  • bzoj 1433: [ZJOI2009]假期的宿舍【匈牙利算法】

    i能睡j床的连边(i,j),跑最大匹配或者最大流,然后看看人数能不能对上总数即可

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=1005;
    int T,n,a[N],b[N],h[N],cnt,con,ans,lk[N],v[N],ti;
    struct qwe
    {
        int ne,to;
    }e[N*N];
    void add(int u,int v)
    {
        cnt++;
        e[cnt].ne=h[u];
        e[cnt].to=v;
        h[u]=cnt;
    }
    bool dfs(int u)
    {
        for(int i=h[u];i;i=e[i].ne)
    		if(v[e[i].to]!=ti)
    		{
    			v[e[i].to]=ti;
    			if(!lk[e[i].to]||dfs(lk[e[i].to]))
    			{
    				lk[e[i].to]=u;
    				return 1;
    			}
    		}
        return 0;
    }
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            memset(h,0,sizeof(h));
            memset(v,0,sizeof(v));
            memset(lk,0,sizeof(lk));
            con=0,ans=0,ti=0;
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
    			scanf("%d",&a[i]);
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&b[i]);
                if(a[i]&&(b[i]==0))
                {
                    add(i,i);
                    con++;
                }
                else if(!a[i])
    				con++;
            }
            for(int i=1;i<=n;i++)
    			for(int j=1,x;j<=n;j++)
    			{
    				scanf("%d",&x);
    				if(x&&a[j])
    					add(i,j);
    			}
            for(int i=1;i<=n;i++)
    			if((a[i]&&!b[i])||!a[i])
    			{
    				ti++;
    				if(dfs(i))
    					ans++;
    			}
            if(ans==con)
    			puts("^_^");
            else
    			puts("T_T");
        }
        return 0;
    }
    
  • 相关阅读:
    第四周作业
    RHEL6+GFS2+MYSQL高可用
    第三周作业
    第二周作业
    centos7 安装redis 开机启动
    无线网卡连接网络后共享给本地有线网卡使用(Win10)
    第一周作业
    2019.8.13加入博客园
    智力题
    Python入门基础学习(模块,包)
  • 原文地址:https://www.cnblogs.com/lokiii/p/9706115.html
Copyright © 2011-2022 走看看