分类
标签
2-SAT AC自动机 BFS CDQ dfs DP fail树 FFT FFT&NTT FWT hash KD-Tree KMP LCA SPFA STL Tarjan Treap Trie 主席树 乱搞 二分 二分图匹配 二分答案 二维SPFA 交互 位运算 其他 最小生成树 分块 区间DP 半平面交 博弈论 可持久化 可持久化Trie树 后缀数组 图库 平衡树 并查集 插头DP 数学 数论 无旋Treap 日记 暴力 权值树状数组 栈 树DP 树套树 树状数组 树贪心 概率DP 模拟 欧拉定理 点分治 状压DP 生成函数 矩阵乘 线性规划 线段树 组合 网络流 群论 莫比乌斯反演 计算几何 贪心 费用流 高斯消元
584 字
3 分钟
[ZJOI2007]矩阵游戏
题目描述
小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏——矩阵游戏。矩阵游戏在一个N *N黑白方阵进行(如同国际象棋一般,只是颜色是随意的)。每次可以对该矩阵进行两种操作:行交换操作:选择 矩阵的任意两行,交换这两行(即交换对应格子的颜色)列交换操作:选择矩阵的任意行列,交换这两列(即交换 对应格子的颜色)
游戏的目标,即通过若干次操作,使得方阵的主对角线(左上角到右下角的连线)上的格子均为黑 色。对于某些关卡,小Q百思不得其解,以致他开始怀疑这些关卡是不是根本就是无解的!!于是小Q决定写一个程 序来判断这些关卡是否有解。
输入
第一行包含一个整数T,表示数据的组数。接下来包含T组数据,每组数据第一行为一个整数N,表示方阵的大 小;接下来N行为一个N*N的01矩阵(0表示白色,1表示黑色)。
输出
输出文件应包含T行。对于每一组数据,如果该关卡有解,输出一行Yes;否则输出一行No。
样例输入
2
2
0 0
0 1
3
0 0 1
0 1 0
1 0 0
样例输出
No
Yes
【数据规模】
对于100%的数据,N ≤ 200
题解
我们发现在同一行或同一列的一直在同一行或同一列。
所以这道题就是要求是否能找到不同行列的一个匹配覆盖n个点
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct edge
{
int END, next;
}v[40005];
int first[205],p;
void add(int a,int b)
{
v[p].END = b;
v[p].next = first[a];
first[a] = p++;
}
int link[205];
bool vis[205];
int find(int x)
{
for (int i = first[x]; i != -1; i = v[i].next)
{
if(!vis[v[i].END])
{
vis[v[i].END] = 1;
if(link[v[i].END]==-1||find(link[v[i].END]))
{
link[v[i].END] = x;
return 1;
}
}
}
return 0;
}
int main()
{
int T, a;
scanf("%d", &T);
while (T--)
{
memset(first, -1, sizeof(first));
p = 0;
memset(link, -1, sizeof(link));
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
{
scanf("%d", &a);
if (a)
add(i, j);
}
int ans = 0;
for (int i = 1; i <= n; i++)
{
memset(vis, 0, sizeof(vis));
if (find(i))
ans++;
}
if(ans == n)
printf("Yes\n");
else
printf("No\n");
}
}