I - Swap(交换行列是对角线都为1)

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?

InputThere 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.OutputFor 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
/*可以锁定行,来选择列和它匹配,
将选择的列移动到和该行形成对角线上是1的位置,
比如和第一行匹配的列,就要移动要第一列,第二行的,就到第二列。
其实就是对第i行,找一个第i个数是1的列和它匹配,
然后看是否是最大匹配!*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int vis[1000];
int dp[1000][1000];
int dis[1000];
int a[1000],b[1000];
int n;
int un,vn;
int find(int x)
{
    for(int i=1;i<=n;i++)
    {
        if(!vis[i]&&dp[x][i])
        {
            vis[i]=1;
            if(dis[i]==0||find(dis[i]))
            {
                dis[i]=x;
                return 1;
            }
        }
    }
    return 0;
}
int maxp()
{
    int ans=0;
    memset(dis,0,sizeof(dis));
    for(int i=1;i<=n;i++)
    {
        memset(vis,0,sizeof(vis));
        if(find(i)) ans++;
    }
    return ans;
}
int main()
{
    while(cin>>n&&n)
    {
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                cin>>dp[i][j];
            }
        }
        int ans=maxp();
        /*for(int i=1;i<=n;i++)
        printf("%d*\n",dis[i]);*/
        if(ans!=n) printf("-1\n");/*如果最大匹配不等于n,那么肯定是错的,输出-1*/ 
        else
        {
            int num=0;
            for(int i=1;i<=n;i++)//从每一行开始 
            {
                int k;
                for(k=1;k<=n;k++)//对应每一列
                    if(dis[k]==i)//就是第k列中第i行对应的数值为1 
                        break;
                if(i!=k)//不是对角线的时候进行交换行和列 
                {
                    a[num]=i;//
                    b[num++]=k;//
                    swap(dis[i],dis[k]);
                }
            }
            printf("%d\n",num);
            for(int i=0;i<num;i++)
            printf("C %d %d\n",a[i],b[i]);
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/csx-zzh/p/13399887.html