巴黎公社社员造船厂Project1129研制成功

时间:2019-06-28 21:02:21   收藏:0   阅读:115

题面

这道题神啊.

看了一下午没有思路,感觉是二分图没有深刻理解,又重新看了一遍蓝书上的二分图,还打了道题练手,然而还是没有想出这道题......

于是恰饭回来决定看下题解,恍然大悟.

同志们可以把每一个点看做一条匹配边,把它的的行数和列数连一条边,会发现整幅图是一组匹配.

在交换行和列的时候,相当于在匈牙利算法中进行协商的过程,所以对最大匹配不变.

如果交换后可以有n个及以上的匹配,就说明一定可以实现题意.

配图如下(图里的字体有点小请见谅):

技术图片

技术图片

然后就是跑一个裸的匈牙利,求出匹配个数就可以了.

代码:


#pragma GCC diagnostic error "-std=c++11"
#pragma GCC target("sse2")
#pragma GCC optimize(3)
#pragma GCC target("avx")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;

struct edge
{
    int to,next;
}e[1000010];

int t,n,size,CommunismParty_cnt;
int head[1000010],match[1000010];
bool flag[1000010];

inline void EdgeAdd(int,int);
inline void Hungary();
inline bool find(int);

int main()
{
    scanf("%d",&t);
    for(int _=1;_<=t;_++)
    {
        scanf("%d",&n);
        CommunismParty_cnt=0;
        size=0;
        memset(head,-1,sizeof(head));
        memset(match,0,sizeof(match));
        memset(e,0,sizeof(e));
        for(int __=1;__<=n;__++)
        {
            for(int ___=1;___<=n;___++)
            {
                int CommunistYouthLeague_color;
                scanf("%d",&CommunistYouthLeague_color);
                if(CommunistYouthLeague_color==1)
                {
                    EdgeAdd(__,___);
                }
            }
        }
        Hungary();
        printf("%s\n",CommunismParty_cnt>=n?"Yes":"No");
    }
return 0;
}

inline void EdgeAdd(int from,int to)
{
    e[++size].to=to;
    e[size].next=head[from];
    head[from]=size;
}

inline void Hungary()
{
    for(int _=1;_<=n;_++)
    {
        memset(flag,false,sizeof(flag));
        if(find(_)==true)
        {
            CommunismParty_cnt++;
        }
    }
}

inline bool find(int from)
{
    for(int _=head[from];_!=-1;_=e[_].next)
    {
        int to=e[_].to;
        if(flag[to]==false)
        {
            flag[to]=true;
            if(match[to]==0||find(match[to])==true)
            {
                match[to]=from;
                return true;
            }
        }
    }
return false;
}
评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!