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]); } } }