您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: