TJU / HDU Matrix Swapping // MAXMATCH

3295.   Matrix Swapping Time Limit: 1.0 Seconds    Memory Limit: 65536K    Special Judge
Total Runs: 408    Accepted Runs: 108



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?

Source: Multi-School Training Contest - TOJ Site #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), separated 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, bN). Any correct answer will be accepted, but M should not 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

Author:HE, Liang

 

Note: Special judge problem, you may get "Wrong Answer" when output in wrong format.

 

 

 

这道题出的很好,的确。

刚开始我一直在思考,到底能不能用匹配做他。因为我在想是否交换两行会导致无效的转换。

后来想了想,这道题目,其实只是为了让我们去找N个不同行不同列的1,所以我们在交换行或列的时候不会影响到已经在对角线上的元素了(这一点我还是有一些疑惑,我加了一些保证他不改变对角线上元素的判断语句,但都WA,也不知道为什么)

另外就是输出交换的语句的时候,集中在要么行交换,要么列交换,在这二者中选一个就可以了。

 

#include<stdio.h>
#include<string.h>
int n;
int map[101][101],link[101];
bool mat[101][101],used[101];
int change[101][2];
bool can(int t)
{
    for(int i=1;i<=n;i++)
    if(used[i]==false&&mat[t][i])
    {
        used[i]=true;
        if(link[i]==-1||can(link[i]))
        {
            link[i]=t;
            return true;
        }
    }
    return false;
}
int MaxMatch()
{
    memset(link,-1,sizeof(link));
    for(int i=1;i<=n;i++)
    {
        memset(used,false,sizeof(used));
        if(!can(i)) return false;
    }
    return true;
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        int cas=0;
        for(int i=1;i<=n;i++)
          for(int j=1;j<=n;j++)
          {
              scanf("%d",&map[i][j]);
              if(map[i][j]==1) mat[i][j]=true,cas++;
              else mat[i][j]=false;
          }

          //if(cas==n*n) printf("0/n");
        //else
        if(cas<n||!MaxMatch()) printf("-1/n");
        else
        {
            int cnt=0;
            //printf("%d  %d/n",link[1],link[2]);
            for(int i=1;i<=n;i++)//对行进行匹配
            {
                if(link[i]==i) continue;//这个列上的元素已经在对角线上,对角线:I==J
                int j;
                for(j=1;j<=n;j++)
                {
                    if(link[j]==i)  break;
                }
                int temp=link[i];
                link[i]=link[j];
                link[j]=temp;
                change[++cnt][0]=i;
                change[cnt][1]=j;
            }
            printf("%d/n",cnt);
            for(int i=1;i<=cnt;i++)
            printf("C %d %d/n",change[i][0],change[i][1]);
        }
    }
    return 0;
}

你可能感兴趣的:(Integer,each,Matrix,output,Training,Numbers)