[bzoj1059][ZJOI2007]矩阵游戏_二分图最大匹配
2024-08-28 21:41:52
矩阵游戏 bzoj-1059 ZJOI-2007
题目大意:给定一个n*n的棋盘,上面有一些格子被染黑,剩下都是白色。你每次可以交换两列或者两行,问你能否通过一系列操作使得棋盘的主对角线上的格子全是黑色。
注释:$1\le n\le 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\n",work()?"Yes":"No");
}
return 0;
}
小结:二分图真的是好东西啊qwq。
最新文章
- crontab介绍
- highcharts的表名
- jquery 选择器(name,属性,元素)大全
- IOS系列swift语言之课时八
- .NET使用Com组件的一点点教训笔记~
- C#搭建足球赛事资料库与预测平台(1) 基本介绍
- 单身狗进化——求n!的位数
- MySQL Show命令的使用
- CentOS6.5配置MySQL主从同步
- asterisk webrtc使用SIPML5初体验
- oracle查看经常使用的系统信息
- java is-a、has-a和like-a、组合、聚合和继承 两组概念的区别
- 那些令人惊艳的TensorFlow扩展包和社区贡献模型
- mac 配置vue+sanic环境准备工作
- windows下使用electron+sqlite3
- Webpack 模块处理
- Ubuntu 12.04 安装socks5代理服务器dante-server
- requests-1快速学习
- 2016级算法第五次上机-B.Bamboo&;APTX4844魔发药水
- Java程序员自我介绍