hdu-2819.swap(二分匹配 + 矩阵的秩基本定理)
时间:2019-09-02
本文章向大家介绍hdu-2819.swap(二分匹配 + 矩阵的秩基本定理),主要包括hdu-2819.swap(二分匹配 + 矩阵的秩基本定理)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
Swap
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5728 Accepted Submission(s): 2157
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”.
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
Recommend
gaojie
这个题一开始没有想到是二分匹配,主要是不知道这个定理.
矩阵的秩:
一般矩阵经过初等变换之后得到的阶梯矩阵中,不全为0的行数为行秩,不全为0的列的个数为列秩,一个矩阵的行秩等于列秩等于矩阵的秩.
矩阵的秩的一般定理:
初等变换不能改变矩阵的秩.
1 /************************************************************************* 2 > File Name: hdu-2819.swap.cpp 3 > Author: CruelKing 4 > Mail: 2016586625@qq.com 5 > Created Time: 2019年09月02日 星期一 17时56分18秒 6 本题大意:给定一个n × n 的0 or 1矩阵,问你若只交换某些行和列(行之间进行交换,列之间进行交换)能否使得最后的矩阵在从左上角到右下角的对角线上元素都为1. 7 本题思路:线性代数里我们学过初等变换不会改变矩阵的秩,因此如果一个矩阵满秩,那么必定有解,如何判断矩阵是否满秩呢?因为是0 or 1矩阵,因此,原矩阵经过变换后得到的阶梯矩阵也都只有0 or 1,如果其中某两列的元素完全相等,或者某一列中本来就不存在1那么转换之后的阶梯矩阵自然也就不会满秩。所以我们可以对行和列缩点,判断是否每一列都有独特的一行与之对应,如果说有两列的1都存在与同一行,那么必定无法匹配,所以我们就想到了二分匹配,让行缩点为x,列缩点为y,匹配之后,如果最大匹配为n那么匹配成功,否则说明矩阵非满秩,如何输出解呢?我们遍历所有列,如果发现有一列与他匹配的行不与他的标号相等,则说明这个(i, j)位于第i行第j列,那么我们把第j列换到第i列即可.也就是交换j与linker[j],交换了之后肯定要改变其匹配状态,也就是让匹配i的行和匹配j的行再互换。 8 ************************************************************************/ 9 10 #include <cstdio> 11 #include <cstring> 12 #include <algorithm> 13 using namespace std; 14 15 const int maxn = 100 + 5, maxm = 1000 + 5, inf = 0x3f3f3f3f; 16 17 typedef pair<int, int> pii; 18 int n, linker[maxn], g[maxn][maxn]; 19 bool used[maxn]; 20 pii path[maxm]; 21 int tot; 22 23 bool dfs(int u) { 24 for(int v = 1; v <= n; v ++) { 25 if(!used[v] && g[u][v]) { 26 used[v] = true; 27 if(linker[v] == -1 || dfs(linker[v])) { 28 linker[v] = u; 29 return true; 30 } 31 } 32 } 33 return false; 34 } 35 36 int main() { 37 while(~scanf("%d", &n)) { 38 tot = 0; 39 for(int i = 1; i <= n; i ++) { 40 for(int j = 1; j <= n; j ++) { 41 scanf("%d", &g[i][j]); 42 } 43 } 44 memset(linker, -1, sizeof linker); 45 int res = 0; 46 for(int i = 1; i <= n; i ++) { 47 memset(used, false, sizeof used); 48 if(dfs(i)) res ++; 49 } 50 if(res != n) printf("%d\n", -1); 51 else { 52 for(int i = 1; i <= n; i ++) { 53 while(i != linker[i]) { 54 path[tot ++] = make_pair(i, linker[i]); 55 swap(linker[i], linker[linker[i]]); 56 } 57 } 58 printf("%d\n", tot); 59 for(int i = 0; i < tot; i ++) { 60 printf("C %d %d\n", path[i].first, path[i].second); 61 } 62 } 63 } 64 return 0; 65 }
原文地址:https://www.cnblogs.com/bianjunting/p/11449162.html
- Eureka 服务上下线监控
- 程序员面试50题(1)—查找最小的k个元素[算法]
- Netty4自带编解码器详解
- C和指针小结(C/C++程序设计)
- Netty-整合Protobuf高性能数据传输
- Netty-整合kryo高性能数据传输
- 40个重要的HTML 5面试问题及答案
- js调用原生API--陀螺仪和加速器
- OpenDaylight开发-DataStoreChange监听器三种类型
- express模拟接口
- spring boot开发的日志系统
- elasticsearch 5.0.1安装analysis-ik分词器
- Spring Cloud中Feign如何统一设置验证token
- laravel+react+webpack+babel+gulp的配置
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- socket.io实践干货
- 0800-5.16.2-如何禁用Hue中Oozie的部分Action
- linux ulimit 调优
- 初识ABP vNext(3):vue对接ABP基本思路
- 0801-什么是Apache Ranger - 4 - Resource vs Tag Based Policies
- IDA-3D技术细节分析
- 0802-Cloudera Data Center7.1.3正式GA
- 2017,科学使用strace神器(附代码,举栗子)
- kubernete编排技术四:Job和CronJob
- Go 视图模板篇(二):模板指令
- go语言学习(五):通道的用法
- PHP无锁内存nosql---Yac的实战
- 0803-什么是Apache Ranger - 5 - Hive Plugin
- 2017年的golang、python、php、c++、c、java、Nodejs性能对比[续]
- go语言学习(四):数组和切片