2011-0072
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
题意:
{{{
给定一个n*n的矩阵,矩阵元素只有'U'和'D'两种,可以进行交换行当操作,问能否经过操作使得矩阵对角线元素全部为'U'。
}}}
解法:
{{{
因为若最后能够成功,说明每一行都有一个'U'和每一列对应,这是一个二分匹配模型,如果能够完全匹配那么说明可以达到要求的状态否则不行
}}}
代码:
{{{
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 256;
#define _clr(x) memset(x, 0xff, sizeof(int) * MAXN)
bool mat[MAXN][MAXN];
int m1[MAXN], m2[MAXN];
char s[MAXN];
int gao(int m, int n, const bool mat[][MAXN], int * match1, int * match2) {
int s[MAXN + 1], t[MAXN], p, q, ret = 0, i, j, k;
_clr(match1);
_clr(match2);
for (i = 0; i < m; ret += (match1[i++] >= 0)) {
_clr(t);
for (s[p = q = 0] = i; p <= q && match1[i] < 0; p++) {
k = s[p];
for (j = 0; j < n && match1[i] < 0; j++) {
if (mat[k][j] && t[j] < 0) {
s[++q] = match2[j];
t[j] = k;
if (s[q] < 0) {
for (p = j; p >= 0; j = p) {
match2[j] = k = t[j];
p = match1[k];
match1[k] = j;
}
}
}
}
}
}
return ret;
}
int main() {
int i, j, k;
while (1 == scanf("%d", &k)) {
for (i=0; i<k; ++i) {
scanf("%s", s);
for (j=0; j<k; ++j) mat[i][j] = s[j] == 'U';
}
puts(gao(k, k, mat, m1, m2) == k ? "YES" : "NO");
}
return 0;
}
}}}
[by delta_4d]
题意:
给定一个n*n的矩阵,矩阵元素只有'U'和'D'两种,可以进行交换行当操作,问能否经过操作使得矩阵对角线元素全部为'U'。
解法:
因为若最后能够成功,说明每一行都有一个'U'和每一列对应,这是一个二分匹配模型,如果能够完全匹配那么说明可以达到要求的状态否则不行
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 256;
#define _clr(x) memset(x, 0xff, sizeof(int) * MAXN)
bool mat[MAXN][MAXN];
int m1[MAXN], m2[MAXN];
char s[MAXN];
int gao(int m, int n, const bool mat[][MAXN], int * match1, int * match2) {
int s[MAXN + 1], t[MAXN], p, q, ret = 0, i, j, k;
_clr(match1);
_clr(match2);
for (i = 0; i < m; ret += (match1[i++] >= 0)) {
_clr(t);
for (s[p = q = 0] = i; p <= q && match1[i] < 0; p++) {
k = s[p];
for (j = 0; j < n && match1[i] < 0; j++) {
if (mat[k][j] && t[j] < 0) {
s[++q] = match2[j];
t[j] = k;
if (s[q] < 0) {
for (p = j; p >= 0; j = p) {
match2[j] = k = t[j];
p = match1[k];
match1[k] = j;
}
}
}
}
}
}
return ret;
}
int main() {
int i, j, k;
while (1 == scanf("%d", &k)) {
for (i=0; i<k; ++i) {
scanf("%s", s);
for (j=0; j<k; ++j) mat[i][j] = s[j] == 'U';
}
puts(gao(k, k, mat, m1, m2) == k ? "YES" : "NO");
}
return 0;
}
[by delta_4d]