HDU-2819(二分图匹配+记录路径)

题目:HDU - 2819 

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

求出最大匹配。若最大匹配小于n,就不能。

之后输出交换的路径,逐行遍历,如果第i行匹配的值不是第i列(主对角线的x和y当然相等了),那就再次遍历寻找哪行匹配的是第i列。假如,我们找到第k行匹配的是第i列,那我们就将i和k进行交换,注意,交换之后我们要将他们的匹配值也要交换,因为操作是再上一次操作之后进行的
 

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>

using namespace std;

const int maxn = 110;
int un,vn;
int g[maxn][maxn];
int linker[maxn];
bool used[maxn];
int n;
bool dfs(int u)
{
    for(int v = 1;v <= n;v ++)
    {
        if(g[u][v] && !used[v])
        {
            used[v] = true;
            if(linker[v] == -1 || dfs(linker[v]))
            {
                linker[v] = u;
                return true;
            }
        }
    }
    return false;
}

int hungary()
{
    int res = 0;
    memset(linker,-1,sizeof(linker));
    for(int u = 1;u <= n;u ++)
    {
        memset(used,false,sizeof(used));
        if(dfs(u)) res ++;
    }
    return res;
}

int main()
{
    int i,j;
    int a[10000];
    int b[10000];
    while(cin >> n)
    {
        un = vn = n;
        memset(g,0,sizeof(g));
        for(i = 1;i <= n;i ++)
        {
            for(j = 1;j <= n;j ++)
            {
                cin >> g[i][j];
            }
        }
        int ans = hungary();
        int res = 0;
        if(ans < n)
        {
            cout << "-1" << endl;
            continue;
        }
        for(i = 1;i <= n;i ++)
            {
                for(j = i;j <= n;j ++)
                {
                    if(linker[j] == i) break;
                }
                if(j != i)
                {
                    a[res] = i;
                    b[res ++] = j;
                    int t = linker[i];
                    linker[i] = linker[j];
                    linker[j] = t;
                }
            }
        cout << res << endl;
        for(i = 0;i < res;i ++)
            printf("C %d %d\n",a[i],b[i]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/guagua_de_xiaohai/article/details/85237321