题意:给你一个矩阵,每个格子是0或者1,每次操作可以任意交换两行或者两列,问是否可以使得主对角线的所有点都为1,如果没有,则输出-1,否则输出交换操作。
分析:行列匹配+暴力找解,只移动行或者列就行。
代码:
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
const int maxn=1005;
const int maxm=1000005;
struct EdgeNode
{
int to;
int next;
}edge[maxm];
int head[maxn],cnt;
void add(int x,int y)
{
edge[cnt].to=y;
edge[cnt].next=head[x];
head[x]=cnt++;
//printf("%d %d\n",x,y);
}
void init()
{
cnt=0;
memset(head,-1,sizeof(head));
}
int n,m,v[maxn],pre[maxn];
int dfs(int x)
{
int y;
for(int i=head[x];i!=-1;i=edge[i].next)
{
y=edge[i].to;
if(!v[y]){
v[y]=1;
if(!pre[y]||dfs(pre[y])){
pre[y]=x;
return true;
}
}
}
return false;
}
int erfenpipei()
{
int sum=0;
memset(pre,0,sizeof(pre));
for(int i=1;i<=n;i++){
memset(v,0,sizeof(v));
if(dfs(i))sum++;
}
return sum;
}
int main()
{
int i,j,x,ans;
int U[maxn],V[maxn];
while(~scanf("%d",&n))
{
init();
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
scanf("%d",&x);
if(x)add(i,j);
}
}
ans=0;
int k=erfenpipei();
if(k<n)printf("-1\n");
else{
for(i=1;i<=n;i++){
if(pre[i]==i)continue;
for(j=i+1;j<=n;j++){
if(pre[j]==i){
U[++ans]=i; V[ans]=pre[i];
pre[j]=pre[i];
}
}
}
printf("%d\n",ans);
for(i=1;i<=ans;i++)printf("R %d %d\n",U[i],V[i]);
}
}
return 0;
}