关闭

hdu2819 Swap--最大匹配数

标签: 匈牙利最大匹配数HDUC++二分图
591人阅读 评论(1) 收藏 举报
分类:

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2819


题意:给定一个n*n的矩阵,格子数字0或者1,通过交换两行或两列使对角线都是1。若不能,输出-1;若可以,输出交换次数,并且输出交换的行或者列。

如果某行或者某列全是0。那怎么换都没办法的。
否则,一定能换出来。
这个动动脑子想一下可以明白的。

其次要明确:只交换行或者只交换列都是可以换出来的。
这个动动脑子想一下也可以明白的。

明确了这两点,这问题就变成了二分图的匹配问题。
二分图左边的节点为每一行的行号
二分图右边的节点为每一行中出现的“1”对应的列号


#define _CRT_SECURE_NO_DEPRECATE 

#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#define INF 99999999;
using namespace std;

int n;
int a[110][110];
int match[110];
int vis[110];

int dfs(int u)
{
	for (int v = 1; v <= n; v++)
	{
		if (a[u][v] && !vis[v])
		{
			vis[v] = 1;
			if (match[v] == -1 || dfs(match[v]))
			{
				match[v] = u;
				return 1;
			}
		}
	}
	return 0;
}

int hungarian()
{
	int ans = 0;
	memset(match, -1, sizeof(match));

	for (int i = 1; i <= n; i++)
	{
		memset(vis, 0, sizeof(vis));
		ans += dfs(i);
	}
	return ans;
}

int main()
{
	while (~scanf("%d", &n))
	{
		memset(a, 0, sizeof(a));

		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				scanf("%d", &a[i][j]);

		if (hungarian() != n)
			printf("-1\n");
		else
		{
			int num = 0;
			int L[110], R[110];
			for (int i = 1; i <= n; i++)
			{
				if (i != match[i])
				{
					for (int j = 1; j <= n; j++)
					{
						if (i == match[j])
						{
							L[num] = i;
							R[num] = j;
							num++;
							swap(match[i], match[j]);
							break;
						}
					}
				}
			}

			printf("%d\n", num);
			for (int i = 0; i < num; i++)
				printf("C %d %d\n", L[i], R[i]);
		}
	}
	return 0;
}



1
0
查看评论

hdu2819Swap (行列匹配,输出交换路径)

Swap Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1453 Accepted Submission(s): 491 Special...
  • u010372095
  • u010372095
  • 2014-08-02 13:32
  • 1081

【图论】【二分图匹配】[HDU2819]Swap

题目 分析:在对角线上全是1,逆向思考这个问题,将对角线上的1回到他们原来的地方后,发现这些1中没有任何两个在同一行或同一列,也就是这个图是一个置换矩形。 将每一行,每一列编号,分别作为x部和y部,将1所在的行列连边,求最大匹配。 至于输出方案,...
  • outer_form
  • outer_form
  • 2015-08-26 20:18
  • 459

HDU2819Swap(二分图最大匹配)

题目大意:交换图的某些行或者是某些列(可以都换),使得这个N*N的图对角线上全部都是1. 分析: 这里先说明的一点就是,如果通过交换某些行没有办法的到解的话,那么只交换列 或者 既交换行又交换列 那也没办法得到解。其实个人感觉这个可以用矩阵的秩来解释,所有的对角线都是1,所以也就是矩阵的秩就是...
  • Rain722
  • Rain722
  • 2017-06-07 19:15
  • 173

HDU 2819 Swap (最大二分匹配+输出路径)

题目大意就是给出一个矩阵,每个格子里面要么是0, 要么是1;是否能够经过交换(交换行或者列)使得主对角线上都是1。 其实就行和列的匹配,左边是行,右边是列,然后如果行列交点是1,那么就可以匹配,看是否为完美匹配,然后输出怎么交换的。开始很蒙的,后来仔细去想,可以这样理解,想要对角线上都是1,那么我...
  • AClion
  • AClion
  • 2013-05-05 19:58
  • 842

HDU 2819 Swap(二分图匹配)

HDU 2819 Swap(二分图匹配) http://acm.hdu.edu.cn/showproblem.php?pid=2819 题意:        给定一个矩阵,矩阵元素取值为0或1,每次操作可以交换任意两行或两列,要求对于给定矩...
  • u013480600
  • u013480600
  • 2014-08-17 21:25
  • 758

HDU2819-Swap

Swap                                         ...
  • a664607530
  • a664607530
  • 2017-03-12 22:55
  • 192

hdu 2819 Swap(二分图最大匹配,输出路径)

Swap Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2712  ...
  • acm_cxq
  • acm_cxq
  • 2016-07-29 08:22
  • 232

hdu 2819 Swap 二分图的最大匹配

//hdu 2819 //直接按照给定的矩阵建图 //判断匹配是否能达到n //然后选择排序确定交换顺序。 #include #include #include using namespace::std; const int INF=0x7fffffff; const int N=110; int ...
  • u012936765
  • u012936765
  • 2015-07-25 09:16
  • 226

hdu2819

/* 分析:     苍天呐~,ac了- -,1WA囧~,二分匹配的水题。     线性代数里面学的么,如果存在ans,那么只交换行、 或只交换列都能抵达ans状态。     所以两个集合,一个是行1(固定不变的行,相当于 固定...
  • Ice_Crazy
  • Ice_Crazy
  • 2013-03-02 14:40
  • 921

算法学习-最长括号匹配

题目 给定字符串,仅包含左括号‘(’和右括号‘)’,它可能不是括号匹配的,设计算法,找出最长匹配的括号子串,返回该子串的长度。 如: (():2 ()():4 ()(()):6 (()()):6 分析 1、记起始匹配位置start=-1;最大匹配长度ml=0;最大匹配长度是每个右括号出栈...
  • HelloNiGeSB
  • HelloNiGeSB
  • 2016-11-15 13:47
  • 637
    个人资料
    • 访问:445375次
    • 积分:7726
    • 等级:
    • 排名:第3279名
    • 原创:395篇
    • 转载:52篇
    • 译文:0篇
    • 评论:46条
    最新评论