题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2819
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
题目翻译:
给定一个 N+N 矩阵,每个条目等于 0 或 1。您可以交换任意两行或任何两列。您能找到一种方法,使所有的对角线条目等于1?
输入
输入中有几个测试用例。每个测试用例的第一行是整数 N(1 <= N <= 100)。然后 N 行跟随,每个线包含 N 个数字 (0 或 1),按空格分隔,指示 N+N 矩阵。
输出
对于每个测试用例,第一行包含交换 M 的数量。然后,M 行跟随,其格式为"R a b"或"C a b",指示交换行 a 和行 b,或交换列 a 和列 b.(1 <= a,b <= N)。任何正确答案都将被接受,但 M 应大于 1000。
如果不可能使所有对角线条目等于 1,则只输出一个包含"-1"的条目.
比较经典的二分图的题,其实不难看出X点集就是点的x坐标,Y点集就是y坐标。然后求出二分图的最大匹配,如果最大匹配数不等于N,则表示不能。否则对最大匹配后的二分图中的每个X点集中的进行遍历,如果X点集和Y点集的编号相同,表示不用交换。如果不相同,那么遍历后面的X点集,把满足条件的X点集与当前点集进行交换,并记录下来。
附:其实我们可以发现这样一个规律,如果能够通过交换得到符合条件的矩阵,那么就一定能通过行交换得到。
#include <bits/stdc++.h>
using namespace std;
int nxt[10005],visited[105],G[105][105];
int n;
int L[10005],R[10005];
int find(int u){
for(int v = 1;v<=n;++v){
if(!visited[v]&&G[u][v]){
visited[v]=1;
if(nxt[v]==-1||find(nxt[v])){
nxt[v]=u;
return 1;
}
}
}
return 0;
}
int match()
{
int ans=0;
memset(nxt,-1,sizeof(nxt));
for(int i = 1;i<=n;++i){
memset(visited,0,sizeof(visited));
if(find(i))
ans++;
}
return ans;
}
int main(int argc, char** argv) {
while(cin>>n){
memset(G,0,sizeof(G));
for(int i = 1;i<=n;++i){
for(int j = 1;j<=n;++j){
cin>>G[i][j];
}
}
int num=match();
if(num!=n){
cout<<"-1"<<endl;
continue;
}
int cnt=0;
for(int i = 1;i<=n;++i){
if(i!=nxt[i]){
for(int j=i+1;j<=n;j++){
if(i==nxt[j]){
L[cnt]=i;
R[cnt++]=j;
swap(nxt[i],nxt[j]);
break;
}
}
}
}
cout<<cnt<<endl;
for(int i = 0;i<cnt;i++) cout<<'C'<<' '<<L[i]<<' '<<R[i]<<endl;
}
return 0;
}
有关二分图匹配的资料和知识可以参考我的这篇文章:https://blog.csdn.net/qq_43472263/article/details/96831025