Swap——hdu 2819

Swap

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2152    Accepted Submission(s): 764
Special Judge


Problem Description
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?
 
Input
There are several test cases in the input. The first line of each test case is an integer N (1 <= N <= 100). Then N lines follow, each contains N numbers (0 or 1), separating by space, indicating the N*N matrix.
 
Output
For each test case, the first line contain the number of swaps M. Then M lines follow, whose format is “R a b” or “C a b”, indicating swapping the row a and row b, or swapping the column a and column b. (1 <= a, b <= N). Any correct answer will be accepted, but M should be more than 1000.

If it is impossible to make all the diagonal entries equal to 1, output only one one containing “-1”. 
 

 

Sample Input
2
0 1
1 0
2
1 0
1 0
 
Sample Output
1 R 1 2 -1
 
Source
 
 题意:如果可以交换行列,问主对角线能不能全为1
分析:要想主对角线全为1很明显要有N个行列不想同的点就行了,可以用二分图匹配计算出来多能有几个。如果小与N就不能。输出要是对的就行,不必和答案一样
 
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 
 5 using namespace std;
 6 
 7 #define N 1100
 8 
 9 int n, vis[N], used[N], a[N], b[N];
10 int maps[N][N];
11 
12 int found(int u)
13 {
14     for(int i = 1; i <= n; i++)
15     {
16         if(!vis[i] && maps[u][i])
17         {
18             vis[i] = 1;
19             if(!used[i] || found(used[i]))
20             {
21                 used[i] = u;
22                 return true;
23             }
24         }
25     }
26     return false;
27 }
28 int main()
29 {
30     int w;
31 
32     while(scanf("%d", &n) != EOF)
33     {
34         memset(vis, 0, sizeof(vis));
35         memset(used, 0, sizeof(used));
36         memset(maps, 0, sizeof(used));
37         memset(a, 0, sizeof(a));
38         memset(b, 0, sizeof(b));
39 
40         int ans = 0;
41 
42         for(int i = 1; i <= n; i++)
43             for(int j = 1; j <= n; j++)
44                 scanf("%d", &maps[i][j]);
45 
46         for(int i = 1; i <= n; i++)
47         {
48             memset(vis, 0, sizeof(vis));
49             if(found(i))
50                 ans++;
51         }
52         if(ans < n)
53         {
54             printf("-1\n");
55             continue;
56         }
57 
58         w = 0;
59         for(int i = 1; i <= n; i++)
60         {
61             while(used[i] != i)
62             {
63                 a[w] = i;
64                 b[w] = used[i];
65                 swap(used[a[w]], used[b[w]]);  // 如果该行匹配不是自身,就交换匹配。
66                 w++;
67             }
68         }
69         printf("%d\n", w);
70         for(int i = 0; i < w; i++)
71             printf("C %d %d\n", a[i], b[i]);
72 
73     }
74     return 0;
75 }

 

转载于:https://www.cnblogs.com/Tinamei/p/4740610.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值