Swap
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2282 Accepted Submission(s): 827
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”.
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
真心觉得这题思路巧妙。。
当原矩阵中第i行第j列值为1,则令G[i][j]为1,否则为0.G[i][j]表示将第j列与第i列互换,可以使原矩阵中第i行第i列值为1.这样我们可以得到一种构造的方法。首先对G图做二分匹配,若匹配结果中i与j有连边,我们就想办法令最终的矩阵中原矩阵第j列放在最终矩阵第i列上,如果匹配数为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;Mx[u]=i;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; } inline void Swap(int& a,int& b){ int t=a;a=b;b=t; } 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||vis[My[i]]||vis[i])){ ++sum; ans[sum][0]=i;ans[sum][1]=My[i]; vis[My[i]]=true;My[i]=My[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; }