HDU2819(KB10-E 二分图最大匹配)

Swap

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3800    Accepted Submission(s): 1401
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

2009 Multi-University Training Contest 1 - Host by TJU

按行交换。对行进行1-n编号,对列也进行编号。

若第i行的第j1、j2……列有1,则节点i与j1、j2……连边。

二分图跑最大匹配,为完美匹配方可。

matching数组保存每个点的匹配,模拟一下交换输出答案。

  1 //2017-08-26
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <iostream>
  5 #include <algorithm>
  6
  7 using namespace std;
  8
  9 const int N = 100000;
 10 const int M = 5000000;
 11 int head[N], tot;
 12 struct Edge{
 13     int to, next;
 14 }edge[M];
 15
 16 void init(){
 17     tot = 0;
 18     memset(head, -1, sizeof(head));
 19 }
 20
 21 void add_edge(int u, int v){
 22     edge[tot].to = v;
 23     edge[tot].next = head[u];
 24     head[u] = tot++;
 25
 26     edge[tot].to = u;
 27     edge[tot].next = head[v];
 28     head[v] = tot++;
 29 }
 30
 31 int n;
 32 int matching[N];
 33 int check[N];
 34 bool dfs(int u){
 35     for(int i =  head[u]; i != -1; i = edge[i].next){
 36         int v = edge[i].to;
 37         if(!check[v]){//要求不在交替路
 38             check[v] = 1;//放入交替路
 39             if(matching[v] == -1 || dfs(matching[v])){
 40                 //如果是未匹配点,说明交替路为增广路,则交换路径,并返回成功
 41                 matching[u] = v;
 42                 matching[v] = u;
 43                 return true;
 44             }
 45         }
 46     }
 47     return false;//不存在增广路
 48 }
 49
 50 //hungarian: 二分图最大匹配匈牙利算法
 51 //input: null
 52 //output: ans 最大匹配数
 53 int hungarian(){
 54     int ans = 0;
 55     memset(matching, -1, sizeof(matching));
 56     for(int u = 1; u <= n; u++){
 57         if(matching[u] == -1){
 58             memset(check, 0, sizeof(check));
 59             if(dfs(u))
 60               ans++;
 61         }
 62     }
 63     return ans;
 64 }
 65
 66 const int MAXID = 100;
 67 int a[N], b[N], cnt;
 68
 69 int main()
 70 {
 71     std::ios::sync_with_stdio(false);
 72     //freopen("inputE.txt", "r", stdin);
 73     while(cin>>n){
 74         init();
 75         int v;
 76         for(int i = 1; i <= n; i++){
 77             for(int j = 1; j <= n; j++){
 78                 cin>>v;
 79                 if(v){
 80                     add_edge(i, j+MAXID);
 81                 }
 82             }
 83         }
 84         int match = hungarian();
 85         if(match != n)cout<<-1<<endl;
 86         else{
 87             for(int i = 1; i <= n; i++)
 88                   matching[i]-=100;
 89             cnt = 0;
 90             for(int i = 1; i <= n; i++){
 91                 for(int j = 1; j <= n; j++){
 92                     if(i == j)continue;
 93                     if(matching[j] == i){
 94                         swap(matching[i], matching[j]);
 95                         a[cnt] = i;
 96                         b[cnt++] = j;
 97                     }
 98                 }
 99             }
100             cout<<cnt<<endl;
101             for(int i = 0; i < cnt; i++)
102                   cout<<"R "<<a[i]<<" "<<b[i]<<endl;
103         }
104     }
105
106     return 0;
107 }
时间: 2024-11-04 20:54:51

HDU2819(KB10-E 二分图最大匹配)的相关文章

匈牙利算法dfs模板 [二分图][二分图最大匹配]

最近学了二分图最大匹配,bfs模板却死活打不出来?我可能学了假的bfs 于是用到了dfs模板 寻找二分图最大匹配的算法是匈牙利算法 匈牙利算法的主要程序是寻找增广路 寻找增光路是过程是:从一个未经配对的点出发,历经未配边.匹配边.未配边.匹配边.未配边....最终到达一个未配点的过程,只要把路径中的未配边和匹配边的“身份”对调,匹配就加一了.这就是一个寻找增广路的过程,通过不断寻找增广路,可以找到最大的匹配. 1 #include<cstdio> 2 #include<cstring&g

图论——LCA、强联通分量、桥、割顶、二分图最大匹配、网络流

A: 交通运输线 时间限制: 5 Sec  内存限制: 128 MB 题目描述 战后有很多城市被严重破坏,我们需要重建城市.然而,有些建设材料只能在某些地方产生.因此,我们必须通过城市交通,来运送这些材料的城市.由于大部分道路已经在战争期间完全遭到破坏,可能有两个城市之间没有道路.当然在运输线中,更不可能存在圈. 现在,你的任务来了.给你战后的道路情况,我们想知道,两个城市之间是否存在道路,如果存在,输出这两个城市之间的最短路径长度. 输入 第一行一个整数Case(Case<=10)表示测试数据

POJ 2226二分图最大匹配

匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名.匈牙利算法是基于Hall定理中充分性证明的思想,它是二部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法. #include<stdio.h> #include<string.h> #include<stdlib.h> int n1,n2; char map[1005][1005]; //数组开大点 int mapx[1005][1005],mapy[1005]

【Codevs1922】骑士共存问题(最小割,二分图最大匹配)

题意: 在一个n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些方格设置了障碍,骑士不得进入. 对于给定的n*n个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑士,使得它们彼此互不攻击. n<=200,m<=n^2 思路:经典的二分图最大匹配问题,采用黑白点染色的思想. 如果按照相邻点黑白不同染色,可以发现每次跳到的点必定与现在所在点不同色,二分图最大匹配即可. 这里用最小割来解决,因为不能允许任何黑白点之间的任何一条边有流量,符合最小割的思想. 1

POJ2239 Selecting Courses(二分图最大匹配)

题目链接 N节课,每节课在一个星期中的某一节,求最多能选几节课 好吧,想了半天没想出来,最后看了题解是二分图最大匹配,好弱 建图: 每节课 与 时间有一条边 1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <algorithm> 6 #include <vector> 7 using namespa

二分图最大匹配总结

hdoj1528 二分匹配模版: 代码: 1 #include<stdio.h> 2 #include<iostream> 3 #include<string.h> 4 #include<algorithm> 5 #include<math.h> 6 using namespace std; 7 #define N 220 8 9 int n, maps[N][N], vis[N], used[N]; 10 11 struct node 12 {

POJ - 1422 Air Raid 二分图最大匹配

题目大意:有n个点,m条单向线段.现在问要从几个点出发才能遍历到所有的点 解题思路:二分图最大匹配,只要一条匹配,就表示两个点联通,两个点联通只需要选取其中一个点即可,所以有多少条匹配,就可以减去多少个点 #include<cstdio> #include<cstring> using namespace std; const int N = 130; int g[N][N], vis[N], link[N]; int n, m; void init() { memset(g, 0

&quot;《算法导论》之‘图’&quot;:不带权二分图最大匹配(匈牙利算法)

博文“二分图的最大匹配.完美匹配和匈牙利算法”对二分图相关的几个概念讲的特别形象,特别容易理解.本文介绍部分主要摘自此博文. 还有其他可参考博文: 趣写算法系列之--匈牙利算法 用于二分图匹配的匈牙利算法 1. 前言 二分图:简单来说,如果图中点可以被分为两组,并且使得所有边都跨越组的边界,则这就是一个二分图.准确地说:把一个图的顶点划分为两个不相交集 U 和V ,使得每一条边都分别连接U.V中的顶点.如果存在这样的划分,则此图为一个二分图.二分图的一个等价定义是:不含有「含奇数条边的环」的图.

[HDU] 2063 过山车(二分图最大匹配)

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=2063 女生为X集合,男生为Y集合,求二分图最大匹配数即可. 1 #include<cstdio> 2 #include<iostream> 3 #include<string.h> 4 #include<algorithm> 5 #include<math.h> 6 #include<stdbool.h> 7 #include<ti