SwapTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1046 Accepted Submission(s): 348 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
Sample Output
Source
Recommend
gaojie
|
=====================================题目大意=====================================
给出一个N阶的01方阵,求解通过交换行和交换列使得方阵的主对角线元素全部为1的任意一种方案。
=====================================算法分析=====================================
在给定的方阵中选取N个两两之间不同行不同列的1,然后便一定可以通过只交换行(或只交换列)移动这些1以得到所需的方阵。
显然二分图的最大匹配:将行和列作为两个点集,矩阵中的元素1作为连接其所在行和所在列的边,使用匈牙利算法求解即可。
=======================================代码=======================================
#include<stdio.h>
#include<string.h>
int N,Linker[105],RecordSwap[105][2];
bool Edge[105][105],Vis[105];
void Swap(int &A,int &B)
{
int tmp=A; A=B; B=tmp;
}
bool DFS(int U)
{
for(int v=1;v<=N;++v)
{
if(Edge[U][v]&&!Vis[v])
{
Vis[v]=true;
if(Linker[v]==-1||DFS(Linker[v]))
{
Linker[v]=U;
return true;
}
}
}
return false;
}
int Hungary()
{
memset(Linker,-1,sizeof(Linker));
int ans=0;
for(int u=1;u<=N;++u)
{
memset(Vis,0,sizeof(Vis));
if(DFS(u)) { ++ans; }
}
return ans;
}
int main()
{
while(scanf("%d",&N)==1)
{
for(int i=1;i<=N;++i)
{
for(int j=1;j<=N;++j)
{
scanf("%d",&Edge[i][j]);
}
}
if(Hungary()<N)
{
printf("-1\n"); continue;
}
int sum=0;
for(int i=1;i<=N;++i) if(Linker[i]!=i)
{
for(int j=i+1;j<=N;++j) if(Linker[j]==i)
{
++sum;
RecordSwap[sum][0]=i;
RecordSwap[sum][1]=j;
Swap(Linker[i],Linker[j]);
}
}
printf("%d\n",sum);
for(int i=1;i<=sum;i++)
{
printf("C %d %d\n",RecordSwap[i][0],RecordSwap[i][1]);
}
}
return 0;
}