hdu2818行列匹配+排序

题意:给定一个矩阵,矩阵上有的数字是1,有的是0,给定两种操作,交换某两行或者某两列,问是否能置换出对角线为1的矩阵

题解:能够置换出对角线是1的矩形要求有n个1既不在同一行也不再同一列,即行列匹配,所以匹配很简单,关键是怎么求出交换的过程,

cx[i] 表示第i行与第cx[i]列匹配,即第i行要变成第cx[i]行
所以将cx从小到大排序,记录交换的的下标,那么就是所需要的结果。因为要求交换次数不能超过1000,所以用选择排序

 1 #include <stdio.h>
 2 #include <string.h>
 3 const int N =    100 + 10;
 4 int Map[N][N];
 5 int cx[N],cy[N];
 6 int a[N];
 7 bool vis[N];
 8 int n;
 9 struct node
10 {
11     int x,y;
12 }ans[1111];
13 bool dfs(int u)
14 {
15     for(int i=0; i<n; ++i)
16     {
17         if(!vis[i] && Map[u][i])
18         {
19             vis[i] = true;
20             if(cy[i]==-1 || dfs(cy[i]))
21             {
22                 cy[i] = u;
23                 cx[u] = i;
24                 return true;
25             }
26         }
27     }
28     return false;
29 }
30 int MaxMatch()
31 {
32     memset(cx, -1, sizeof(cx));
33     memset(cy, -1, sizeof(cy));
34     int cnt = 0;
35     for(int i=0; i<n; ++i)
36     {
37         if(cx[i] == -1)
38         {
39             memset(vis, 0, sizeof(vis));
40             cnt += dfs(i);
41         }
42     }
43     return cnt;
44 }
45 int main()
46 {
47     int i,j;
48     while(scanf("%d",&n)!=EOF)
49     {
50         for(i=0; i<n; ++i)
51             for(j=0; j<n; ++j)
52                 scanf("%d",&Map[i][j]);
53         if(MaxMatch() == n)  // 那么可以置换出对角线是1的矩形
54         {    
55             int cnt = 0;
56             for(i=0; i<n; ++i)
57                 a[i] = cx[i];//cx[i] 表示第i行与第cx[i]列匹配,即第i行要变成第cx[i]行
58             //所以将cx从小到大排序,记录交换的的下标,那么就是所需要的结果
59             for(i=0; i<n-1; ++i)
60             {
61                 int index = i;
62                 for(j=i+1; j<n; ++j)
63                 {
64                     if(a[j] < a[index])
65                         index = j;
66                 }
67                 if(index != i)
68                 {
69                     int tmp = a[i];
70                     a[i] = a[index];
71                     a[index] = tmp;
72                     ans[cnt].x = i;
73                     ans[cnt++].y = index;
74                 }
75             }
76             printf("%d\n",cnt);
77             for(i=0; i<cnt; ++i)
78                 printf("R %d %d\n",ans[i].x+1, ans[i].y+1);
79         }
80         else
81             puts("-1");
82     }
83     return 0;
84 }
85 
86 
87 /*
88 3
89 0 1 0
90 0 0 1
91 1 0 0
92 */

 

posted @ 2014-10-13 22:05  justPassBy  阅读(168)  评论(0编辑  收藏  举报