这个题就是给你一个只含有0和1的矩阵, 问你能否通过行列交换使得对角线上的元素全为1, 首先需要注意的是我们仅通过行交换或者列交换就可以使得矩阵满足条件, 然后我们将行和列看成点, 矩阵中1的元素看成边, 建立一个有向图, 求出行列的最大匹配数,即可。。代码如下:
#include <bits/stdc++.h> using namespace std; int N; int mat[105][105]; int p[105]; //第i列匹配的行 int vis[105]; bool dfs(int u) { for(int v=1; v<=N; v++) if(mat[u][v]&&!vis[v]) { vis[v] = true; if(p[v]==-1 || dfs(p[v])) { p[v] = u; //第v行匹配第u列 return true; } } return false; } int a[1000], b[1000]; int cnt; int main() { while(scanf("%d", &N) == 1) { for(int i=1; i<=N; i++) for(int j=1; j<=N; j++) { scanf("%d", &mat[i][j]); } memset(p, -1, sizeof(p)); int pipei = 0; for(int i=1; i<=N; i++) { memset(vis, 0, sizeof(vis)); if(dfs(i)) ++pipei; } if(pipei != N) { printf("-1 "); continue; } cnt = 0; for(int i=1; i<=N; i++) //寻找 { int j; for(j=i; j<=N&&p[j]!=i; j++); if(i != j) { a[cnt] = i; b[cnt++] = j; swap(p[i], p[j]); //交换第i列 和 第j列 } } printf("%d ", cnt); for(int i=0; i<cnt; i++) { printf("C %d %d ", a[i], b[i]); } } return 0; }