zoukankan      html  css  js  c++  java
  • [bzoj1059][ZJOI2007]矩阵游戏_二分图最大匹配

    矩阵游戏 bzoj-1059 ZJOI-2007

    题目大意:给定一个n*n的棋盘,上面有一些格子被染黑,剩下都是白色。你每次可以交换两列或者两行,问你能否通过一系列操作使得棋盘的主对角线上的格子全是黑色。

    注释:$1le nle 200$。


    想法

    我们发现一个小性质,就是两个格子如果同行那么无论如何操作他们都同行。如果同列那么无论任何时刻他们都同列。

    这样的话我们就是要找到每行每列都需要有黑格子。

    我们将行和列抽象成点直接跑匈牙利判断一下最大匹配是不是n即可。

    最后,附上丑陋的代码... ...

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 210 
    using namespace std;
    int fr[N<<1]; bool line[N][N<<1],used[N<<1];
    int a[N][N];
    int n;
    inline char nc() {static char *p1,*p2,buf[100000]; return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}
    int rd() {int x=0; char c=nc(); while(!isdigit(c)) c=nc(); while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=nc(); return x;}
    bool find(int x)
    {
    	for(int i=n+1;i<=n<<1;i++) if(line[x][i]&&!used[i])
    	{
    		used[i]=true; if(!fr[i]||find(fr[i])) {fr[i]=x; return true;}
    	}
    	return false;
    }
    void init()
    {
    	memset(fr,0,sizeof fr); memset(used,false,sizeof used);
    	memset(line,false,sizeof line);
    }
    bool work()
    {
    	for(int i=1;i<=n;i++)
    	{
    		memset(used,false,sizeof used);
    		if(!find(i)) return false;
    	}
    	return true;
    }
    int main()
    {
    	int cases=rd(); while(cases--)
    	{
    		init();
    		n=rd(); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)
    		{
    			a[i][j]=rd(); if(a[i][j]) line[i][j+n]=true;
    		}
    		printf("%s
    ",work()?"Yes":"No");
    	}
    	return 0;
    }
    

    小结:二分图真的是好东西啊qwq。

  • 相关阅读:
    正则表达式match方法和search方法
    正则表达式(基础篇1)
    动画
    重绘和重排(回流)
    数组常用的10个方法
    css3只需一招,将网站变成灰色的
    Python-类的几种调用方法
    Codeforces Global Round 8 C. Even Picture(构造)
    Codeforces Global Round 8 D. AND, OR and square sum(位运算)
    Codeforces Round #650 (Div. 3) C. Social Distance
  • 原文地址:https://www.cnblogs.com/ShuraK/p/9801500.html
Copyright © 2011-2022 走看看