您的位置:首页 > 其它

HDU-2819-Swap [二分匹配][输出路径]

2017-08-23 09:17 417 查看
题目传送门

题意:给定一个只有0 1的矩形,问能否通过交换行列使对角线上的数全为1,如果可以输出交换的路径。

思路:首先通过匈牙利算法算出最大匹配,如果最大匹配数不等于矩阵的行数,则必然不会成功。只交换行,或者只交换列都可以交换出来。

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>

using namespace std;

int n;
bool path[110][110];
bool used[110];
int match[110];
bool Dfs(int x)
{
for (int i = 1; i <= n; i++)
{
if (!used[i] && path[x][i])
{
used[i]=1;
if (!match[i] || Dfs(match[i]))
{
match[i] = x;
return true;
}
}
}
return false;
}
int Matching()
{
int ans = 0;
memset(match,0, sizeof(match));
for (int i = 1; i <= n; i++)
{
memset(used, false, sizeof(used));
if (Dfs(i))
{
ans++;
}
}
return ans;
}
int main(void)
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);

while (~scanf("%d", &n))
{
memset(path, false, sizeof(path));
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
int x;
scanf("%d", &x);
path[i][j] = x;
}
}
int ans = Matching();
if (ans!=n)
{
printf("-1\n");
continue;
}
int L[110], R[110];
int cnt=0;
for (int i = 1; i <= n; i++)
{
if (match[i] != i)
{
for (int j = 1; j <= n; j++)
{
if (i==match[j])
{
L[cnt] = i;
R[cnt] = j;
cnt++;
swap(match[i], match[j]);
break;
}
}
}
}
printf("%d\n", cnt);
for (int i = 0; i < cnt; i++)
printf("C %d %d\n", L[i], R[i]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: