hdu 2819 Swap
Description
Given an N*N matrix with each entry equal to 0 or 1. You can swap any two rows or any two columns. Can you find a way to make all the diagonal entries equal to 1?
Input
There are several test cases in the input. The first line of each test case is an integer N (1 <= N <= 100). Then N lines follow, each contains N numbers (0 or 1), separating by space, indicating the N*N matrix.
Output
For each test case, the first line contain the number of swaps M. Then M lines follow, whose format is “R a b” or “C a b”, indicating swapping the row a and row b, or swapping the column a and column b. (1 <= a, b <= N). Any correct answer will be accepted, but M should be more than 1000.
If it is impossible to make all the diagonal entries equal to 1, output only one one containing “-1”.
Sample Input
2
0 1
1 0
2
1 0
1 0
Sample Output
1
R 1 2
-1
题目大意:给你一个由0和1组成的矩阵,问能不能通过交换行和列来使这个矩阵中的G[i][i] = 1(对角线)。不能输出-1,能的话输出交换次数和交换策略。
解题思路:如果这个矩阵有一行或者一列全为零,则这个矩阵不可能达到目标状态。左边为1所在的坐标的行号,右边为1所在的坐标的列号,进行匹配,若求出的最大匹配等于n,则可以交换到目标状态。策略的话,根据匹配时的记录数组来找就行了(详细见代码)。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
using namespace std;
const int N = 1105;
typedef long long ll;
int n;
int G[N][N], R[N];
int a[N], b[N];
int vis[N];
bool input() {
memset(R, 0, sizeof(R));
memset(G, 0, sizeof(G));
int a, flag, flag2 = 1;
for (int i = 1; i <= n; i++) {
flag = 0;
for (int j = 1; j <= n; j++) {
scanf("%d", &a);
if (a) {
flag = 1;
G[i][j] = 1;
}
}
if (!flag) flag2 = 0;
}
if (!flag2) {
printf("-1\n");
return false;
}
return true;
}
int find(int x) {
for (int i = 1; i <= n; i++) {
if (G[x][i] && !vis[i]) {
vis[i] = 1;
if (R[i] == 0 || find(R[i])) {
R[i] = x;
return 1;
}
}
}
return 0;
}
int hungary() {
int ans = 0;
for (int i = 1; i <= n; i++) {
memset(vis, 0, sizeof(vis));
if (find(i)) ans++;
}
return ans;
}
void solve() {
int ans = 0;
int m;
for (int i = 1; i <= n; i++) {
m = i;
for (int j = i; j <= n; j++) {
if (R[j] <= R[m]) m = j;
}
if (m != i) {
a[ans] = m, b[ans] = i;
ans++;
int temp = R[m];
R[m] = R[i];
R[i] = temp;
}
}
printf("%d\n", ans);
for (int i = 0; i < ans; i++) {
printf("C %d %d\n", a[i], b[i]);
}
}
int main() {
while (scanf("%d", &n) != EOF) {
if (!input()) continue;
int ans = hungary();
if (ans != n) {
printf("-1\n");
continue;
}
solve();
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不可转载。