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?
题意:
给了一个N*N的网格,上面有0和1,每次可以调换两行或两列,问是否能换到主对角线都是1。
如果格子是1,就将它的行和列建边,然后进行二分图匹配,每行仅和一列匹配,这样将那一列的1换到对应行的对角线位置就可以了。
1 #include<stdio.h>
2 #include<string.h>
3
4 const int maxn=205;
5 const int maxm=1e5+5;
6
7 int head[maxn],point[maxm],nxt[maxm],size;
8 int match[maxn],vis[maxn];
9 int M[105][105];
10 int r[105],c[105];
11
12 void init(){
13 memset(head,-1,sizeof(head));
14 size=0;
15 memset(match,-1,sizeof(match));
16 }
17
18 void add(int a,int b){
19 point[size]=b;
20 nxt[size]=head[a];
21 head[a]=size++;
22 }
23
24 int dfs(int s){
25 for(int i=head[s];~i;i=nxt[i]){
26 int j=point[i];
27 if(!vis[j]){
28 vis[j]=1;
29 if(match[j]==-1||dfs(match[j])){
30 match[j]=s;
31 return 1;
32 }
33 }
34 }
35 return 0;
36 }
37
38 int main(){
39 int n;
40 while(scanf("%d",&n)!=EOF){
41 init();
42 for(int i=1;i<=n;++i){
43 for(int j=1;j<=n;++j){
44 scanf("%d",&M[i][j]);
45 if(M[i][j]==1)add(i,n+j);
46 }
47 }
48 int ans=0;
49 for(int i=1;i<=n;++i){
50 memset(vis,0,sizeof(vis));
51 if(dfs(i)==1)ans++;
52 }
53 if(ans!=n)printf("-1
");
54 else{
55 for(int i=1;i<=n;++i){
56 int p=match[i+n];
57 r[p]=i;
58 c[i]=p;
59 }
60 printf("%d
",n);
61 for(int i=1;i<=n;++i){
62 if(c[i]==i)printf("R %d %d
",i,i);
63 else{
64 printf("R %d %d
",i,c[i]);
65 int rr=r[i],cc=c[i];
66 c[i]=r[i]=i;
67 r[cc]=rr;c[rr]=cc;
68 }
69 }
70 }
71 }
72 return 0;
73 }