hdu2819 swap(二分图匹配)
来源:互联网 发布:布比网络 编辑:程序博客网 时间:2024/05/23 19:19
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”.
题意:给出一个0/1矩阵,问是否可以通过不断交换两行或两列得到一个左上右下对角线全是1的矩阵。如果可以,输出任意方案。(R a b交换a,b两行,C a b交换a,b两列)。有special judge,要求步骤数小于1000。
这题我一开始根本不觉得这和二分图有什么关系。。这几天搜索题做多了,第一反应是构造h函数。。然而这题确实巧妙。你可以先假定有一个主对角线全是1其他全是0的矩阵,然后乱交换几次看看,就有规律了:无论交换哪两行或者两列,得到的都是一个置换矩阵(每行每列仅一个1)。那么问题就显然是求原矩阵中是否包含一个置换矩阵。由于每行每列仅一个一,就将原图中所有行作为X部,列作为Y部,对矩阵中每个1将其行和列连边,检查是否满流即可。
至于输出方案,将那个置换矩阵取出来,再模拟一次给所有1的y坐标升序排序的过程即可。为了让交换次数尽量少,建议手写选择排序。
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define MAXN 250#define MAXM 51000int N, M, cnt;int mat[MAXN][MAXN];struct Node { int to; Node*next; };struct BiGraph { int match[MAXN], xn; bool vis[MAXN]; Node Edge[MAXM*2], *ecnt, *adj[MAXN]; BiGraph() { memset(adj,0,sizeof adj); ecnt=Edge; } void addedge(int a, int b) {++ecnt;ecnt->to = b;ecnt->next = adj[a];adj[a] = ecnt; } bool dfs(int u) {for (Node*p = adj[u]; p; p=p->next) {int &v = p->to;if (vis[v]) continue;vis[v] = 1;if (!match[v] || dfs(match[v])) {match[u] = v; match[v] = u; return 1;}}return 0; } int Maxmatch() {int ans = 0;for (int i = 1; i<=xn; ++i)if (!match[i]) {memset(vis, 0, sizeof vis);ans += dfs(i);}return ans;}} Empty, G;int a[MAXN];int x1[1000], x2[1000];int main(){int i, j;while (~scanf("%d", &N)) {G = Empty;G.xn = N;M = cnt = 0;for (i = 1; i<=N; ++i)for (j = 1; j<=N; ++j) {scanf("%d", &mat[i][j]);if (mat[i][j])G.addedge(i, j+N);}if (G.Maxmatch() < N) {puts("-1");continue;}for (i = 1; i<=N; ++i)for (j = 1; j<=N; ++j)if (mat[i][j] && G.match[i]==j+N)a[++cnt] = j;for (i = 1; i<=N; ++i) {if (a[i] == i) continue;for (j = i; j<=N; ++j)if (a[j] == i) {swap(a[i], a[j]);++M;x1[M] = i; x2[M] = j;break;}}printf("%d\n", M);for (i = 1; i<=M; ++i)printf("R %d %d\n", x1[i], x2[i]);}return 0;}
0 0
- HDU2819 Swap (二分图匹配)
- hdu2819 swap(二分图匹配)
- 【图论】【二分图匹配】[HDU2819]Swap
- hdu2819-Swap(二分图匹配,思路)
- hdu2819 Swap(二分匹配)
- hdu2819 Swap 二分图最大匹配 输出路径
- HDU2819 Swap(二分图匹配匈牙利算法+记录路径)
- hdu2819二分图匹配
- HDU2819 Swap 最大匹配
- hdu2819棋盘游戏(二分图匹配)
- hdu2819 Swap--最大匹配数
- HDU2819 Swap 看似很难的题目其实用二分匹配就解决了
- Swap(hdu2819,最大匹配+记录路径)
- hdu2819 Swap
- HDU2819:Swap
- hdu2819 Swap
- 【HDU2819】Swap
- HDU2819-Swap
- html部分标签学习
- js用正则表达式去除字符串左右空格
- 排序算法总结
- 将一个十六进制字符串转换为十进制数值的问题
- 【剑指Offer面试题】 九度OJ1513:二进制中1的个数
- hdu2819 swap(二分图匹配)
- Hadoop入门进阶课程3--Hadoop2.X64位环境搭建
- Oracle数据库再次安装
- error LNK2001: unresolved external symbol __imp__SetupDiGetDeviceInterfaceDetailA@24
- Scala各种类型实战
- 如何写好技术简历 —— 实例、模板及工具
- Qt使用的一些总结
- iOS webview 和 js 交互
- Qt4.8.6插件化编程例程--仅供参考