hdu3468 Treasure Hunting 二分匹配
//给一个n*m的图
//.表示空白地
//*表示有黄金
//#表示墙
//一个人须要依照A...Z..a..z的顺序以最短路径走到下一个
//每次仅仅能在他的路线上经过的地方取一块黄金
//问最多能取多少黄金
//对于每次起点和终点,用bfs搜索最短路,再用dfs找出最短路线经过的全部点
//对于第i次找最短路线与其走过的点建立边,然后用二分匹配就能找出
#include<iostream>
#include<vector>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std ;
const int maxn = 110 ;
vector<int> vec[maxn] ;
int match[maxn*maxn] ;
int vis[maxn][maxn] ;
int visit[maxn*maxn] ;
char map[maxn][maxn] ;
int pos[maxn*maxn] ;int len ;
int st_x , st_y , en_x, en_y ;
int dx[4] = {0 , 1 , 0 , -1} ;
int dy[4] = {1 , 0 , -1 , 0} ;
int n , m ;
queue<int> que ;
int sum = 0 ;
void dfs(int x , int y , int num)
{
sum++ ;
if(x == st_x && y == st_y)
return ;
if(map[x][y] == '*')
vec[num].push_back(x*m+y) ;
for(int i = 0;i < 4;i++)
{
int nx = x + dx[i] ;
int ny = y + dy[i] ;
if(nx < 0 || nx >= n || ny < 0 || ny >= m || vis[nx][ny] + 1 != vis[x][y])
continue ;
dfs(nx , ny ,num);
}
vis[x][y] = 0 ;
}
int bfs(int num)
{
while(que.size())que.pop() ;
memset(vis, 0 ,sizeof(vis)) ;
que.push(st_x) ;que.push(st_y) ;
vis[st_x][st_y] = 1;
while(que.size())
{
int x = que.front() ; que.pop() ;
int y = que.front() ; que.pop() ;
if(x == en_x && y == en_y)
{
dfs(x , y ,num) ;
return true ;
}
int step = vis[x][y] ;
for(int i = 0;i < 4;i++)
{
int nx = dx[i] + x ;
int ny = dy[i] + y ;
if(nx < 0 || nx >= n || ny < 0 || ny >= m || vis[nx][ny] || map[nx][ny] == '#')
continue ;
vis[nx][ny] = vis[x][y] + 1 ;
que.push(nx);
que.push(ny) ;
}
}
return false ;
}
int find(int u)
{
for(int i = 0;i < vec[u].size() ;i++)
{
int v = vec[u][i] ;
if(!visit[v])
{
visit[v] = 1 ;
if(match[v] == -1 || find(match[v]))
{
match[v] = u ;
return true ;
}
}
}
return false ;
}
int Match()
{
int ans = 0 ;
memset(match , -1 , sizeof(match)) ;
for(int i = 0;i < len - 1;i++)
{
memset(visit ,0 , sizeof(visit)) ;
if(find(i))
ans++ ;
}
return ans ;
}
int main()
{
//freopen("in.txt" ,"r" , stdin) ;
while(~scanf("%d%d" ,&n , &m))
{
memset(pos ,0 , sizeof(pos)) ;
len = 0 ;
for(int i = 0;i < n;i++)
{
scanf("%s" , &map[i]) ;
for(int j = 0;j < m;j++)
if((map[i][j] >= 'a'&&map[i][j] <='z'))
pos[map[i][j]-'a'+26] = i*m + j +1,len++ ;
else if(map[i][j] >= 'A' && map[i][j] <= 'Z')
pos[map[i][j]-'A'] = i*m + j + 1, len++ ;
}
int flag = 0 ;
for(int i = 0;i < len;i++)
{
if(!pos[i])
flag = 1 ;
pos[i]--;
}
if(len < 2 || flag)
{
puts("-1");
continue ;
}
for(int i = 0;i < len - 1;i++)
{
vec[i].clear() ;
st_x = pos[i]/m;st_y = pos[i]%m;
en_x = pos[i+1]/m;en_y = pos[i+1]%m ;
if(!bfs(i))
{
flag = 1;
break ;
}
}
if(flag)puts("-1") ;
else
printf("%d\n" , Match()) ;
}
return 0 ;
}
hdu3468 Treasure Hunting 二分匹配的更多相关文章
- poj 2594 Treasure Exploration (二分匹配)
Treasure Exploration Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 6558 Accepted: 2 ...
- kuangbin带你飞 匹配问题 二分匹配 + 二分图多重匹配 + 二分图最大权匹配 + 一般图匹配带花树
二分匹配:二分图的一些性质 二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j ...
- POJ 1274 The Perfect Stall、HDU 2063 过山车(最大流做二分匹配)
The Perfect Stall Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 24081 Accepted: 106 ...
- [kuangbin带你飞]专题十 匹配问题 二分匹配部分
刚回到家 开了二分匹配专题 手握xyl模板 奋力写写写 终于写完了一群模板题 A hdu1045 对这个图进行 行列的重写 给每个位置赋予新的行列 使不能相互打到的位置 拥有不同的行与列 然后左行右列 ...
- BZOJ 1189 二分匹配 || 最大流
1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1155 Solved: 420[Submi ...
- Kingdom of Obsession---hdu5943(二分匹配)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5943 题意:给你两个数n, s 然后让你判断是否存在(s+1, s+2, s+3, ... , s+n ...
- poj 2060 Taxi Cab Scheme (二分匹配)
Taxi Cab Scheme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 5710 Accepted: 2393 D ...
- [ACM_图论] Sorting Slides(挑选幻灯片,二分匹配,中等)
Description Professor Clumsey is going to give an important talk this afternoon. Unfortunately, he i ...
- [ACM_图论] The Perfect Stall 完美的牛栏(匈牙利算法、最大二分匹配)
描述 农夫约翰上个星期刚刚建好了他的新牛棚,他使用了最新的挤奶技术.不幸的是,由于工程问题,每个牛栏都不一样.第一个星期,农夫约翰随便地让奶牛们进入牛栏,但是问题很快地显露出来:每头奶牛都只愿意在她们 ...
随机推荐
- 自动合法打印VitalSource Bookshelf中的电子书
最近有一本2千多页的在VitalSource中的电子书想转为PDF随时阅读,没料网上找了一圈没有找到合适的.相对好一些的只有一个用Python写的模拟手动打印.于是想到了用AutoHotkey写一个自 ...
- [剑指offer] 1. 二维数组中的查找 (数组)
注意是有序数组!! 思路: 1.利用二维数组由上到下,由左到右递增的规律,选取右上角或者左下角的元素a[m][n]与target进行比较, 当target小于元素a[m][n]时,那么target必定 ...
- 2.安装Cython
许多科学的Python发行版,例如Anaconda,Enthought Canopy和Sage,捆绑Cython并且不需要设置. 与大多数Python软件不同,Cython需要在系统上存在C编译器.获 ...
- java源码之TreeMap
Map的单元是对键值对的处理,之前分析过的两种Map,HashMap和LinkedHashMap都是用哈希值去寻找我们想要的键值对,优点是理想情况下O(1)的查找速度. 那如果我们在一个对查找性能要求 ...
- 【转】C# winform 加载网页 模拟键盘输入自动接入访问网络
[转]C# winform 加载网页 模拟键盘输入自动接入访问网络 声明: 本文原创,首发于博客园 http://www.cnblogs.com/EasyInvoice/p/6070563.html ...
- C++异常注意事项
C++里面catch对于类型转换,限制比参数传递时候要多: 不可以进行标准算术转换和类的自定义转换:在函数参数匹配的过程中,可以进行很多的类型转换.但是在异常匹配的过程中,转换的规则要严厉. 标准算术 ...
- shareSDK的初步使用(shareSDK中微信、qq等兼容问题,以及cocoapods支持架构冲突问题的解决)
第一次使用shareSDK来做第三方分享,可是.昨天一天都是在调试bug,一直错误不断! 先说下我的开发环境: xcode:5.1 真机调试:iPhone5s 我们都知道xcode5.1以后開始是支持 ...
- mysql表空间传输(ERROR 1808) row_format设置
文章结构如下: 从MYSQL5.6版本开始,引入了传输表空间这个功能,可以把一张表从一个数据库移到另一个数据库或者机器上.迁移的时候很方便,尤其是大表. 由于本次达到测试使用版本5.6.38传到5.7 ...
- OKHttp使用简介
现在android网络方面的第三方库很多,volley,Retrofit,OKHttp等,各有各自的特点,这边博客就来简单介绍下如何使用OKHttp. 梗概 OKHttp是一款高效的HTTP客户端,支 ...
- Kettle学习系列之kettle的下载、安装和初步使用(windows平台下)(图文详解)
不多说,直接上干货! kettle的下载 Kettle可以在http://kettle.pentaho.org/网站下载 http://sourceforge.n ...