Swap (二分匹配)

Swap

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

二分最大匹配,难在如何建图。这道题要交换任意两行两列,是的对角线都是1,emmmm不知道是什么知识,如果只交换任意两行不能实现的话,那么只交换任意两列或者行列都交换也是不能实现的,好像是矩阵的秩,线性代数里面的东西,还没学就只好先记着了。如果矩阵中一点是1,那就建图e[i][j]=1,代表着我们一会要将j列拉到与i相对应的列,使得e[i][i]=1。同时,如果这个图的最大匹配不是n的话,那是不能满足条件的,所以输出-1。详细看代码理解吧。

#include<cstdio>
#include<cstring>
using namespace std;
#define N 105
bool G[N][N],vis[N];
int Mx[N],My[N],Nx,Ny;
bool dfs(int u)
{
    for(int i=1; i<=Ny; ++i)
    {
        if(G[u][i]&&!vis[i])
        {
            vis[i]=true;
            if(My[i]==-1||dfs(My[i]))
            {
                My[i]=u;
                return true;
            }
        }
    }
    return false;
}
int MaxMatch()
{
    int ans=0;
    memset(Mx,-1,sizeof(Mx));
    memset(My,-1,sizeof(My));
    for(int i=1; i<=Nx; ++i)
    {
        if(Mx[i]==-1)
        {
            memset(vis,false,sizeof(vis));
            if(dfs(i)) ++ans;
        }
    }
    return ans;
}
int main()
{
    int n,val,sum,ans[N][2];
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=1; i<=n; ++i)
        {
            for(int j=1; j<=n; ++j)
            {
                scanf("%d",&val);
                G[i][j]=(val==0?false:true);
            }
        }
        Nx=Ny=n;
        if(MaxMatch()==n)
        {
            memset(vis,false,sizeof(vis));
            sum=0;
            for(int i=1; i<=n; ++i)//*枚举每一列
            {
                while(!(My[i]==i/*My[i]代表的是行,行数不等于列数*/||vis[My[i]]||vis[i]))
                {
                    ++sum;
                    ans[sum][0]=i;
                    ans[sum][1]=My[i];
                    vis[My[i]]=true;
                    My[i]=My[My[i]];//更换之后的My[i]
                }
            }
            printf("%d\n",sum);
            for(int i=1; i<=sum; ++i) printf("C %d %d\n",ans[i][0],ans[i][1]);
        }
        else printf("-1\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40510246/article/details/81352404