题目链接:https://cn.vjudge.net/problem/HDU-2819

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?

InputThere 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.OutputFor 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

题意:

给出一个N*N的01矩阵,要求你通过一些行交换或者列交换使得矩阵的主对角线上全为1;

题解:

不难想象,进行行列缩点,如果某个位置aij等于1,就往二分图中加入一条边( i , j ),如果求出最大匹配等于N,说明可以通过行列的变换得到目标矩阵;

然后根据匹配情况,输出相应的交换步骤即可;

AC代码:

#include<bits/stdc++.h>
#define MAX 103
#define INF 0x3f3f3f3f
using namespace std;
int n,matrix[MAX][MAX]; struct Hopcroft_Karp{
int edge[MAX][MAX],Mx[MAX],My[MAX],Nx,Ny;
int dx[MAX],dy[MAX],dis;
bool vis[MAX];
void init(int uN,int vN)
{
Nx=uN, Ny=vN;
for(int i=;i<=uN;i++) for(int j=;j<=vN;j++) edge[i][j]=;
}
void addedge(int u,int v){edge[u][v]=;}
bool searchP()
{
queue<int> Q;
dis=INF;
memset(dx,-,sizeof(dx));
memset(dy,-,sizeof(dy));
for(int i=;i<=Nx;i++)
{
if(Mx[i]==-)
{
Q.push(i);
dx[i]=;
}
}
while(!Q.empty())
{
int u=Q.front();Q.pop();
if(dx[u]>dis) break;
for(int v=;v<=Ny;v++)
{
if(edge[u][v] && dy[v]==-)
{
dy[v]=dx[u]+;
if(My[v]==-) dis=dy[v];
else
{
dx[My[v]]=dy[v]+;
Q.push(My[v]);
}
}
}
}
return dis!=INF;
}
bool dfs(int u)
{
for(int v=;v<=Ny;v++)
{
if(!vis[v] && edge[u][v] && dy[v]==dx[u]+)
{
vis[v]=;
if(My[v]!=- && dy[v]==dis) continue;
if(My[v]==- || dfs(My[v]))
{
My[v]=u;
Mx[u]=v;
return true;
}
}
}
return false;
}
int max_match()
{
int ret=;
memset(Mx,-,sizeof(Mx));
memset(My,-,sizeof(My));
while(searchP())
{
memset(vis,,sizeof(vis));
for(int i=;i<=Nx;i++) if(Mx[i]==- && dfs(i)) ret++;
}
return ret;
}
}HK; int main()
{
while(scanf("%d",&n)!=EOF)
{
HK.init(n,n);
for(int i=;i<=n;i++)
{
for(int j=;j<=n;j++)
{
scanf("%d",&matrix[i][j]);
if(matrix[i][j]) HK.addedge(i,j);
}
} int max_match=HK.max_match();
if(max_match==n)
{
queue< pair<int,int> > output;
for(int j=;j<=n;j++)
{
int u1=j, u2=HK.My[j];
int v1=j, v2=HK.Mx[j];
if(u1!=u2)
{
output.push(make_pair(u1,u2));
HK.My[v1]=u1, HK.My[v2]=u2;
HK.Mx[u1]=v1, HK.Mx[u2]=v2;
}
} printf("%d\n",output.size());
while(!output.empty())
{
printf("R %d %d\n",output.front().first,output.front().second);
swap(matrix[output.front().first],matrix[output.front().second]);
output.pop();
}
}
else printf("-1\n");
}
}

PS.刚开始还以为HK算法的模板出错了,吓死了……

PS.注意更改匹配情况时,match数组的变更;

HDU 2819 - Swap - [二分图建模+最大匹配]的更多相关文章

  1. HDU - 2819 Swap(二分图最大匹配)

    Given an N*N matrix with each entry equal to 0 or 1. You can swap any two rows or any two columns. C ...

  2. HDU 2819 Swap(行列式性质+最大匹配)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2819 题目大意:给你一个n*n的01矩阵,问是否可以通过任意交换整行或者整列使得正对角线上都是1. ...

  3. HDU - 2819 Swap (二分图匹配-匈牙利算法)

    题意:一个N*N的01矩阵,行与行.列与列之间可以互换.要求变换出一个对角线元素全为1的矩阵,给出互换的行号或列号. 分析:首先一个矩阵若能构成对角线元素全为1,那么矩阵的秩为N,秩小于N的情况无解. ...

  4. HDU 2819 ——Swap——————【最大匹配、利用linker数组、邻接表方式】

     Swap Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status ...

  5. HDU 2819 Swap(二分图匹配)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=2819 [题目大意] 给出一个棋盘,由白格子和黑格子组成,可以交换棋盘的行列, 使得其主对角线为黑格 ...

  6. E - Swap - hdu 2819(简单二分图匹配)

    题意:如果可以交换行列,问主对角线能不能全为1 分析:要想主对角线全为1很明显要有N个行列不想同的点就行了,可以用二分图匹配计算出来多能有几个.如果小与N就不能.输出要是对的就行,不必和答案一样 ** ...

  7. hdu 2819 Swap

    Swap http://acm.hdu.edu.cn/showproblem.php?pid=2819 Special Judge Problem Description Given an N*N m ...

  8. HDU 2819 — Swap 二分匹配

    Swap Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  9. HDU 2828 Lamp 二分图的最大匹配 模型题

    http://acm.hdu.edu.cn/showproblem.php?pid=2828 给定n个灯,m个开关,使得每栈灯亮,前提是控制这栈灯的开关的状态是其中一个.(题目应该都看得懂) 其实我想 ...

随机推荐

  1. C# AES要解密的数据的长度无效

    加密方式  AES-CBC-128 将解密方法改成如下 public string Decrypt(string toDecrypt, string key) { if (string.IsNullO ...

  2. Java使用String类格式化当前日期

    在输出日期信息时,经常需要输出不同格式的日期格式,本实例中介绍了String字符串类中的日期格式化方法,实例使用不同的方式输出String类的日期格式参数值,组合这些值可以实现特殊格式的日期字符串. ...

  3. 【代码审计】iZhanCMS_v2.1 前台GoodsController.php页面存在SQL注入漏洞分析

      0x00 环境准备 iZhanCMS官网:http://www.izhancms.com 网站源码版本:爱站CMS(zend6.0) V2.1 程序源码下载:http://www.izhancms ...

  4. dedeCMS解码

    var str = 'arrs1[]=99&arrs1[]=102&arrs1[]=103&arrs1[]=95&arrs1[]=100&arrs1[]=98& ...

  5. 如何在LSI MegaRAID BIOS里设定RAID 10与Hot Spare

    1. 同时按下 ”Ctrl + H” 进入MegaRAID WebBIOS 画面,可以看到所有物理硬盘 (Physical Drives) 的信息.请在左边视窗点选“Configuration Wiz ...

  6. U3D功能脚本备忘

    编译器属性 属性 介绍 用例 AddComponentMenu 在Component菜单中添加新的菜单项 [AddComponentMenu("Duan/Script/TestScript& ...

  7. Linux下chkconfig命令详解转载

    chkconfig命令主要用来更新(启动或停止)和查询系统服务的运行级信息.谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接. 使用语法:chkconfig [--ad ...

  8. MVC的简单初步学习(2)

    今天似乎一切是正常的,我们的课依旧在进行着,但是恍惚脑海中并没有那样的平静,不知道在想些什么?而且今天是学习MVC的初步开始,我应该认真地学习才是正确的啊.但是我并不糊涂,今天是周一,也就是刚开始上课 ...

  9. iOS 静态库和动态库(库详解)

    什么是库 ? 库就是程序代码的集合,将N个文件组织起来,是共享程序代码的一种方式.库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行. 库的分类 开源库:源代码是公开的,可以看到每个实现 ...

  10. EGit系列第二篇——关联远程仓库

    网上也有很多代码托管网站支持git,像最出名的GitHub,还有国内支持私有项目的OSC开源中国和CSDN等... 首先得注册个帐号,然后才可以创建仓库 一般都会带一个ReadMe.md,你可以勾选也 ...