hdu 2819(二分图匹配)

此题可有对角线都是1的方阵进行 行变换或列变换 得到。  

如果这样想就可以知道, 每行只选一个列,要把所有的列全部选完, 而且最后只需进行行变换就可以转变成对角线全为一

 

Swap

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 892    Accepted Submission(s): 283
Special Judge


Problem 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
 

 

Source
 

 

Recommend
gaojie
 

 

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
#define N 110

int g[N][N];
int n;
int mark[N],pre[N];

int dfs(int s)
{
    for(int i=1;i<=n;i++)
    {
        if(g[s][i]==0||mark[i]==1) continue;
        mark[i]=1;
        if(pre[i]==-1||dfs(pre[i]))
        {
            pre[i]=s;
            return 1;
        }
    }
    return 0;
}

int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        memset(g,0,sizeof(g));
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                int tmp;
                scanf("%d",&tmp);
                if(tmp==1)
                    g[j][i]=1;
            }
        }
        int sum=0;
        memset(pre,-1,sizeof(pre));
        for(int i=1;i<=n;i++)
        {
            memset(mark,0,sizeof(mark));
            sum+=dfs(i);
        }
        if(sum!=n) printf("-1\n");
        else
        {
            int ans[110];
            int cnt=1;
            for(int i=1;i<=n;i++)
            {
                for(int j=i;j<=n;j++)
                {
                    if(pre[j]==i)
                    {
                        ans[cnt++]=j;
                        swap(pre[j],pre[i]);
                        break;
                    }
                }
            }
            printf("%d\n",n);
            for(int i=1;i<=n;i++)
                printf("R %d %d\n",i,ans[i]);
        }
    }
    return 0;
}

 

posted @ 2013-04-27 20:39  chenhuan001  阅读(167)  评论(0编辑  收藏  举报