题意:
给一个n*n的01矩阵,问能否通过行列交换使得
主对角线上的数都为1
如果能输出交换的过程,如果不能输出-1
思路:
线性代数学过,行列交换都不改变矩阵的秩
三秩相等
如果能改变成主对角线上的数都为1
则原矩阵必为满秩
/* *********************************************** //Author :devil //Created Time :2016/5/10 21:49:26 //************************************************ */ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <cmath> #include <stdlib.h> using namespace std; const int N=110; vector<int>eg[N]; int link[N],a[N*N],b[N*N]; bool vis[N]; bool dfs(int u) { for(int i=0;i<eg[u].size();i++) { int v=eg[u][i]; if(!vis[v]) { vis[v]=1; if(link[v]==-1||dfs(link[v])) { link[v]=u; return 1; } } } return 0; } int main() { //freopen("in.txt","r",stdin); int n,x; while(~scanf("%d",&n)) { memset(link,-1,sizeof(link)); for(int i=1;i<=n;i++) eg[i].clear(); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { scanf("%d",&x); if(x) eg[i].push_back(j); } } int ans=0; for(int i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); ans+=dfs(i); } if(ans<n) { printf("-1 "); continue; } int cnt=0,j; for(int i=1;i<=n;i++) { for(j=1;j<=n;j++) if(link[j]==i) break; if(j!=i) { a[cnt]=i; b[cnt++]=j; swap(link[j],link[i]); } } printf("%d ",cnt); for(int i=0;i<cnt;i++) printf("C %d %d ",a[i],b[i]); } return 0; }