码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 2819 Swap(二分图匹配)

时间:2015-08-30 15:53:11      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:

hdu 2819 Swap

Description
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?

Input
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.

Output
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”.

Sample Input

2
0 1
1 0
2
1 0
1 0

Sample Output

1
R 1 2
-1

题目大意:给你一个由0和1组成的矩阵,问能不能通过交换行和列来使这个矩阵中的G[i][i] = 1(对角线)。不能输出-1,能的话输出交换次数和交换策略。

解题思路:如果这个矩阵有一行或者一列全为零,则这个矩阵不可能达到目标状态。左边为1所在的坐标的行号,右边为1所在的坐标的列号,进行匹配,若求出的最大匹配等于n,则可以交换到目标状态。策略的话,根据匹配时的记录数组来找就行了(详细见代码)。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
using namespace std;

const int N = 1105;
typedef long long ll;
int n;
int G[N][N], R[N];
int a[N], b[N];
int vis[N];

bool input() {
    memset(R, 0, sizeof(R));
    memset(G, 0, sizeof(G));
    int a, flag, flag2 = 1;
    for (int i = 1; i <= n; i++) {
        flag = 0;
        for (int j = 1; j <= n; j++) {
            scanf("%d", &a);                    
            if (a) {
                flag = 1;   
                G[i][j] = 1;
            }
        }   
        if (!flag) flag2 = 0;
    }
    if (!flag2) {
        printf("-1\n");
        return false;
    }
    return true;
}
int find(int x) {
    for (int i = 1; i <= n; i++) {
        if (G[x][i] && !vis[i]) {
            vis[i] = 1; 
            if (R[i] == 0 || find(R[i])) {
                R[i] = x;   
                return 1;
            } 
        }   
    }
    return 0;
}

int hungary() {
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        memset(vis, 0, sizeof(vis));    
        if (find(i)) ans++;
    }
    return ans;
}

void solve() {
    int ans = 0;
    int m;
    for (int i = 1; i <= n; i++) {
        m = i;
        for (int j = i; j <= n; j++) {
            if (R[j] <= R[m]) m = j;    
        }
        if (m != i) {
            a[ans] = m, b[ans] = i;
            ans++;  
            int temp = R[m];
            R[m] = R[i];
            R[i] = temp;
        }
    }
    printf("%d\n", ans);
    for (int i = 0; i < ans; i++) {
        printf("C %d %d\n", a[i], b[i]);
    }

}

int main() {
    while (scanf("%d", &n) != EOF) {
        if (!input()) continue;
        int ans = hungary();
        if (ans != n) {
            printf("-1\n");
            continue;
        }
        solve();
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不可转载。

hdu 2819 Swap(二分图匹配)

标签:

原文地址:http://blog.csdn.net/llx523113241/article/details/48105071

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!