UVALive 6525 Attacking rooks(二分图最大匹配)

Attacking rooks

在一个n*n的图中,‘X’代表卒,在‘.’的地方放置尽量多的车,使得它们不互相攻击。问最多可放置车的数目。

Fire Net一样,但这里图是100*100的,搜索会超时(其实我还脑残的试了试).

正解是二分图匹配,将每行中连续为.的作为X集合中一个点,同样,将每列中连续为.的点作为Y集合中的一个点。对原图中每个‘.‘,将其对应的X集合和Y集合中的标号建边,便形成了二分图,对该图求最大匹配,每形成一个匹配即选择该点放车,那么与它相同编号的行和列都被覆盖了,都不能被选择了。最大匹配数就是最多可以放的车数。

#include <stdio.h>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#define LL long long
#define _LL __int64
using namespace std;
const int INF = 0x3f3f3f3f;
const int mod = 1000000007;
const int maxn = 50010;

struct node
{
	int v;
	int next;
}edge[10010];

char G[110][110];
int mapr[110][110],mapc[110][110];
int n;
int cnt,pre[10010];
int a,b;
int match[10010];
int chk[10010];

void add(int u,int v)
{
	edge[cnt] = ((struct node){v,pre[u]});
	pre[u] = cnt++;
}

void init()
{
	int i,j;
	a = 1,b = 1;
	memset(mapr,0,sizeof(mapr));
	memset(mapc,0,sizeof(mapc));
	cnt = 0;
	memset(pre,-1,sizeof(pre));

	for(int i = 1; i <= n; i++)
	{
		for(int j = 1; j <= n; j++)
		{
			if(G[i][j] == ‘.‘)
			{
				if(G[i][j] != G[i][j-1])
					mapr[i][j] = a++;
				else mapr[i][j] = mapr[i][j-1];
			}
		}
	}

	for(int j = 1; j <= n; j++)
	{
		for(int i = 1; i <= n; i++)
		{
			if(G[i][j] == ‘.‘)
			{
				if(G[i][j] != G[i-1][j])
					mapc[i][j] = b++;
				else mapc[i][j] = mapc[i-1][j];
			}
		}
	}

	for(int i = 1; i <= n; i++)
	{
		for(int j = 1; j <= n; j++)
		{
			if(G[i][j] == ‘.‘)
				add(mapr[i][j], mapc[i][j]);
		}
	}
}

int dfs(int p)
{
	for(int i = pre[p]; i != -1; i = edge[i].next)
	{
		int v = edge[i].v;
		if(!chk[v])
		{
			chk[v] = 1;

			if(match[v] == -1 || dfs(match[v]))
			{
				match[v] = p;
				return 1;
			}
		}
	}
	return 0;
}
int main()
{
	while(~scanf("%d",&n))
	{
		memset(G,‘0‘,sizeof(G));
		for(int i = 1; i <= n; i++)
			scanf("%s",G[i]+1);
		init();
		memset(match,-1,sizeof(match));
		int ans = 0;
		for(int i = 1; i <= a; i++)
		{
			memset(chk,0,sizeof(chk));
			ans += dfs(i);
		}
		printf("%d\n",ans);
	}
	return 0;
}

UVALive 6525 Attacking rooks(二分图最大匹配),布布扣,bubuko.com

时间: 2024-12-09 23:37:33

UVALive 6525 Attacking rooks(二分图最大匹配)的相关文章

UVALive 6525 Attacking rooks

将行中连续的' . '当作X集的一个点,列中连续的' . '看成Y集中的一个点,然后把每一个' . '看成一条边,连接Xi,Yj. 则问题转化成求此二分的最大匹配数.每找到一条匹配边的意义是找到了一个点放置一个,并且覆盖了所在的连续的行和列. 所以答案即为此二分图的最大匹配. 20s的时限,只跑了29ms....这是有多不相信自己的服务器.... #include <iostream> #include <algorithm> #include <cstdlib> #i

UVALive 6525 Attacking rooks 二分匹配 经典题

题目链接:option=com_onlinejudge&Itemid=8&page=show_problem&problem=4536">点击打开链接 题意: 给定n*n的棋盘, 能够在'.'上摆 象棋中的车(X是墙壁) 使得随意两个车都不能互相攻击到 问:最多能摆多少个车. 思路: 二分匹配 1.若没有X.那么做法就是 X点集为行,Y点集为列,对于图上的每一个点所在的行和列(x,y) 建一条边 x->y 2.有了X,那么对于每一个点所在的上方能接触到的X必须

LA 6525 Attacking rooks 二分匹配

题意: 给定n*n的棋盘, 可以在'.'上摆 象棋中的车(X是墙壁) 使得任意两个车都不能互相攻击到 求最多能摆多少个车. 思路:将每行中连续为.的作为X集合中一个点,同样,将每列中连续为.的点作为Y集合中的一个点.对原图中每个'.',将其对应的X 集合和Y集合中的标号建边,便形成了二分图,对该图求最大匹配.详见代码: /********************************************************* file name: LA6525.cpp author :

UVALive 5033 I&#39;m Telling the Truth 二分图最大匹配(略有修改)

I - I'm Telling the Truth Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVALive 5033 Description After this year's college-entrance exam, the teacher did a survey in his class on students' score. There

匈牙利算法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