题意:N * N的 01 矩阵,可以进行两个操作:①把两行交换;②把两列交换。问能不能经过几次操作,使矩阵从左上都右下的对角线上全是 1。
题解:首先进行行交换,列交换的时候这一行的元素相对位置不会变,就相当于矩阵中是否存在n个横坐标,纵坐标都不相同的点。核心算法 -> 匈牙利算法。
CODE:
/* Author: JDD PROG: bzoj1059 矩阵游戏 DATE: 2015.9.24 */ #include <cstdio> #include <cstring> #define REP(i, s, n) for(int i = s; i <= n; i ++) #define REP_(i, s ,n) for(int i = n; i >= s; i --) #define MAX_N 205 using namespace std; int n; bool map[MAX_N][MAX_N], used[MAX_N]; int L[MAX_N]; void init() { scanf("%d", &n); memset(map, 0, sizeof(map)); REP(i, 1, n) REP(j, 1, n){ int x; scanf("%d", &x); if(x) map[i][j] = 1; } memset(L, 0, sizeof(L)); } bool find(int x) { REP(i, 1, n){ if(map[x][i] && !used[i]){ used[i] = 1; if(L[i] == 0 || find(L[i])){ L[i] = x; return 1; } } } return 0; } void doit() { REP(i, 1, n){ memset(used, 0, sizeof(used)); if(!find(i)) { printf("No\n"); return; } } printf("Yes\n"); } int main() { int T; scanf("%d", &T); while(T --){ init(); doit(); } return 0; }