您的位置:首页 > 其它

swap HDU2819 匈牙利算法(二分匹配应用)

2018-02-12 17:22 253 查看
个人感觉这道题非常有意思,其询问对于输入矩阵能否通过一系列交换两行或两列的操作使得矩阵的对角线上全部为1.易见对于每一行,其最后能处在的位置就取决于该行包含1的位置,如1 0 1 0 0,则这一行经过一系列交换之后它必须要位于第一行或第三行,从而相应的变为匹配问题,直接用匈牙利算法解即可。#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
#define MAXN 103
int matrix[MAXN][MAXN];
int N;
typedef int Edge;
void input()
{
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++)
scanf("%d", &matrix[i][j]);
}
}
class bipartiteGraph
{
public:
void transform()
{
left.clear();
right.clear();
for (int i = 0; i < N; i++)
left.push_back(i);
for (int i = 0; i < N; i++)
right.push_back(i);
for (int i = 0; i < N; i++)
edges[i].clear();
for (int i = 0; i < N; i++) {
for(int j=0;j<N;j++)
if (matrix[i][j] == 1) {
edges[i].push_back(j);
}
}
}
void solveBiMatching()
{
memset(edgesFind, 0xff, sizeof(edgesFind));
int sum = 0;
for (int i = 0; i < N; i++) {
memset(edgesVisited, 0, sizeof(edgesVisited));
if (_find(i))
sum++;
}
if (sum < N)
printf("-1\n");
else {
_steps = 0;
memset(edgesVisited, 0, sizeof(edgesVisited));
for (int i = 0; i < N; i++) {
if (!edgesVisited[i]) {
if (edgesFind[i] == i)
edgesVisited[i] = true;
else
_add(i, edgesFind[i]);
}
}
printf("%d\n", _steps);
memset(edgesVisited, 0, sizeof(edgesVisited));
for (int i = 0; i < N; i++) {
if (!edgesVisited[i]) {
if (edgesFind[i] == i)
edgesVisited[i] = true;
else
_print(i, edgesFind[i]);
}
}
}
}
private:
vector<int > left;
vector<int > right;
vector<Edge > edges[MAXN];
bool edgesVisited[MAXN];
int edgesFind[MAXN];
int _steps;
bool _find(int x)
{
for (int i = 0; i < edges[x].size(); i++) {
int u = edges[x][i];
if (!edgesVisited[u]) {
edgesVisited[u] = true;
if (edgesFind[u] < 0 || _find(edgesFind[u])) {
edgesFind[u] = x;
return true;
}
}
}
return false;
}
void _print(int start,int present)
{
edgesVisited[present] = true;
if (edgesFind[present] == start)
printf("R %d %d\n", start+1, present+1);
else {
printf("R %d %d\n", present+1, edgesFind[present]+1);
_print(start, edgesFind[present]);
}
}
void _add(int start, int present)
{
_steps++;
edgesVisited[present] = true;
if (edgesFind[present] != start)
_add(start, edgesFind[present]);
}
};
int main()
{
bipartiteGraph bg;
while (scanf("%d", &N) != EOF) {
input();
bg.transform();
bg.solveBiMatching();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  bipartite matching