hdu 2819 Swap

来源:互联网 发布:linux下卸载oracle11g 编辑:程序博客网 时间:2024/05/01 12:27

Swap
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2268 Accepted Submission(s): 819
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
这一题,怎么说呢,如果不是在做2分法专题的话,不太容易想到用,匈牙利2分匹配法做。一般匈牙利2分匹配可以分为,建图,和匹配两个过程。题目思路就是,用两个不相交集合,行 列,相匹配,如果最大匹配数小于N,没得说,肯定输出-1。如果等于N,说明是可以弄成对角线全为1。关键点在于,怎么输出这个过程,最后的行列关系有点难想,后面给注释。建图原理是:如果某行某列输入为1,那么这行这列存在连接关系,是可以匹配的。

`#include
#include
#include
#include
using namespace std;
int n;
int ma[105][100],mark[105],pei[105];

bool find(int x)
{
for(int i=1;i<=n;i++)
{
if(ma[x][i]&&!mark[i])
{
mark[i]=1;
if(pei[i]==-1||find(pei[i]))
{
pei[i]=x;
return true;
}
}
}
return false;
}

int main()
{
while(cin>>n)
{
int t,ans=0;
int a[105],b[105],k=1;
memset(ma,0,sizeof(ma));
memset(pei,-1,sizeof(pei));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
cin>>t;
if(t)
ma[i][j]=1;//建图
}

    for(int i=1;i<=n;i++)//匹配过程。    {        memset(mark,0,sizeof(mark));        if(find(i))        ans++;    }    if(ans<n)   {    cout<<"-1"<<endl;    continue;   }   for(int i=1;i<=n;i++)//i,表示列,对每列遍历找到一个等于i的行。对角线为(1,1),(2,2),(3,3)这种情况。   {      for(int j=1;j<=n;j++)      {        if(i!=j)//本身肯定不交换        {          if(pei[j]==i)//找到某行对应行等于该列,          {            a[k]=i,b[k]=j;//记录列            swap(pei[i],pei[j]);//交换i,j列对应的行,这里要仔细想。            k++;          }         }      }   }   cout<<k-1<<endl;    for(int i=1;i<k;i++)   {    cout<<"C"<<" "<<a[i]<<" "<<b[i]<<endl;   }}return 0;

}

1 0