HDU - 2819 Swap (二分匹配+输出路径)
2018-03-05 21:01
489 查看
Swap
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4278 Accepted Submission(s): 1581
Special Judge
[align=left]Problem Description[/align] 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?
[align=left]Input[/align] 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.
[align=left]Output[/align] 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”.
[align=left]Sample Input[/align]2
0 1
1 0
2
1 0
1 0
[align=left]Sample Output[/align]1
R 1 2
-1
[align=left]Source[/align] 2009 Multi-University Training Contest 1 - Host by TJU
[align=left]Recommend[/align] gaojie
题意:给你一个矩阵,问你通过交换行或列,能否得到一个正对角线均为一的矩阵。并输出交换的行或列。
解题思路:很容易想到用二分匹配,难点在于如何输出路径。首先,根据矩阵的秩的性质,如果矩阵的秩为N的话,只通过交换行或只通过交换列,就能得到对角线为1的矩阵。根据这个性质,我们可以用选择排序的思想,暴力的去匹配即可。跑完匈牙利算法后我们得到一个match数组,根据这个即可暴力的交换。
#include <iostream>
#include <deque>
#include <stdio.h>
#include <map>
#include <string.h>
#include <algorithm>
#include <vector>
#include <math.h>
#include <stack>
#include <queue>
#include <set>
using namespace std;
typedef long long int ll;
const int MAXN = 500;
int G[MAXN][MAXN]; //连线
int ans1[MAXN], ans2[MAXN];
int cnt;
//二分图匹配部分
int used[MAXN];
int match[MAXN];
int N;
bool hungry(int x)
{
for (int i = 1; i <= N; i++)
{
if (G[x][i] && !used[i])
{
used[i] = 1;
if (match[i] == 0 || hungry(match[i]))
{
match[i] = x;
return true;
}
}
}
return false;
}
int main()
{
while (~scanf("%d", &N))
{
memset(G, 0, sizeof(G));
memset(match, 0, sizeof(match));
cnt = 0;
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++)
scanf("%d", &G[i][j]);
int ans = 0;
for (int i = 1; i <= N; i++)
{
memset(used, 0, sizeof(used));
if (hungry(i))
ans++;
}
if (ans == N)
{
for (int i = 1; i <= N; i++)
{
if (i != match[i])
{
for (int j = i + 1; j <= N; j++)
{
if (match[j] == i)
{
ans1[cnt] = i;
ans2[cnt] = j;
cnt++;
swap(match[i], match[j]);
}
}
}
}
printf("%d\n",cnt);
for(int i=0;i<cnt;i++){
printf("C %d %d\n",ans1[i],ans2[i]);
}
}
else
printf("-1\n");
}
return 0;
}
相关文章推荐
- HDU-2819-Swap [二分匹配][输出路径]
- HDU 2819 Swap (最大二分匹配+输出路径)
- hdu 2819 Swap(二分图最大匹配,输出路径)
- HDU 2819 Swap (二分匹配+破输出)
- hdu 2819 Swap(二分匹配+记录路径,好题)
- hdu2819 Swap(二分匹配)
- HDU 2819 Swap (行列匹配+输出解)
- HDU 2819 Swap (二分图-行列匹配+输出解)
- hdoj 2819 Swap (最大匹配+输出路径)
- hdu 2819 记录路径的二分匹配
- HDU 2819 — Swap 二分匹配
- HDU 2819 Swap 二分匹配
- HDU 2819 Swap (行列匹配+输出解)
- HDU 2819 — Swap 二分匹配
- HDU 2819 Swap(记录二分匹配的过程)
- hdu 2819 Swap【完美二分匹配】
- hdu-2819 Swap (二分匹配)
- HDU 1507 Uncle Tom's Inherited Land*(二分匹配,输出任意一组解)
- HDU 2819 (二分匹配)
- hdu2819 Swap--最大匹配数