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;
}
#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;
}
相关文章推荐
- poj 2536 Gopher II 二分匹配应用 匈牙利算法
- 最大二分匹配(匈牙利算法)
- HDU-1045-Fire Net [二分匹配][匈牙利算法]
- 二分最大匹配--匈牙利算法
- 二分匹配,匈牙利算法
- 二分匹配——匈牙利算法;
- POJ3041《Asteroids》方法:匈牙利算法(最小点覆盖数==最大二分匹配数)
- 匈牙利算法-最大二分匹配
- HDU1083+POJ1469 (匈牙利算法+最大二分匹配)
- 解题报告-HDOJ-2063(最大二分匹配-匈牙利算法)
- 二分匹配(匈牙利算法)【模板】
- 【二分图匹配】最大二分匹配——匈牙利算法
- 二分匹配,匈牙利算法
- hdu2063 过山车 (匈牙利算法 二分匹配)
- 最大二分匹配算法详解(匈牙利)
- 【最大二分匹配匈牙利算法】hdu 3729
- hdu3360+二分匹配(匈牙利算法)
- uva11419 【最大二分匹配求最小点覆盖 匈牙利算法】
- hdu 2444 The Accomodation of Students(二分匹配 匈牙利算法 邻接表实现)
- 二分匹配(匈牙利算法)