//给一个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 二分匹配的更多相关文章

  1. poj 2594 Treasure Exploration (二分匹配)

    Treasure Exploration Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 6558   Accepted: 2 ...

  2. kuangbin带你飞 匹配问题 二分匹配 + 二分图多重匹配 + 二分图最大权匹配 + 一般图匹配带花树

    二分匹配:二分图的一些性质 二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j ...

  3. POJ 1274 The Perfect Stall、HDU 2063 过山车(最大流做二分匹配)

    The Perfect Stall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 24081   Accepted: 106 ...

  4. [kuangbin带你飞]专题十 匹配问题 二分匹配部分

    刚回到家 开了二分匹配专题 手握xyl模板 奋力写写写 终于写完了一群模板题 A hdu1045 对这个图进行 行列的重写 给每个位置赋予新的行列 使不能相互打到的位置 拥有不同的行与列 然后左行右列 ...

  5. BZOJ 1189 二分匹配 || 最大流

    1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1155  Solved: 420[Submi ...

  6. Kingdom of Obsession---hdu5943(二分匹配)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5943 题意:给你两个数n, s 然后让你判断是否存在(s+1, s+2, s+3, ... , s+n ...

  7. poj 2060 Taxi Cab Scheme (二分匹配)

    Taxi Cab Scheme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5710   Accepted: 2393 D ...

  8. [ACM_图论] Sorting Slides(挑选幻灯片,二分匹配,中等)

    Description Professor Clumsey is going to give an important talk this afternoon. Unfortunately, he i ...

  9. [ACM_图论] The Perfect Stall 完美的牛栏(匈牙利算法、最大二分匹配)

    描述 农夫约翰上个星期刚刚建好了他的新牛棚,他使用了最新的挤奶技术.不幸的是,由于工程问题,每个牛栏都不一样.第一个星期,农夫约翰随便地让奶牛们进入牛栏,但是问题很快地显露出来:每头奶牛都只愿意在她们 ...

随机推荐

  1. 2019-03-28 SQL Server Table

    -- table 是实际表 view是虚表.你可以认为view是一个查询的结果 -- 声明@tbBonds table declare @tbBonds table(TrustBondId int n ...

  2. Mysql学习总结(35)——Mysql两千万数据优化及迁移

    最近有一张2000W条记录的数据表需要优化和迁移.2000W数据对于MySQL来说很尴尬,因为合理的创建索引速度还是挺快的,再怎么优化速度也得不到多大提升.不过这些数据有大量的冗余字段和错误信息,极不 ...

  3. Run Nutch In Eclipse on Linux and Windows nutch version 0.9

    Running Nutch in Eclipse Here are instructions for setting up a development environment for Nutch un ...

  4. 一个通用Makefile的编写

    作者:杨老师,华清远见嵌入式学院讲师. 我们在Linux环境下开发程序,少不了要自己编写Makefile,一个稍微大一些的工程下面都会包含很多.c的源文件.如果我们用gcc去一个一个编译每一个源文件的 ...

  5. 对象不支持“abigimage”属性或方法

    在一个网页中用了一个js插件, js文件引用的没有错,代码也和demo差点儿相同,  可是执行时ie的调试工具报了一个错: 解决方式: jquery文件冲突,发现原来自己引过一个 <script ...

  6. C++继承中析构函数 构造函数的调用顺序以及虚析构函数

    首先说说构造函数.大家都知道构造函数里就能够调用成员变量,而继承中子类是把基类的成员变成自己的成员,那么也就是说子类在构造函数里就能够调用基类的成员了,这就说明创建子类的时候必须先调用基类的构造函数, ...

  7. bzoj3444: 最后的晚餐(并查集+组合数学)

    3444: 最后的晚餐 题目:传送门 题解: 考虑有解的情况: 直接上并查集,同一个联通块里的人一定要坐在一起的.不难发现其实对于每个联通块最多就只有两种排列方式,那就直接把大于等于两个人的联通块先去 ...

  8. PyCharm基本设置、常用快捷键

    1. 下载安装 PyCharm官方下载地址:  https://www.jetbrains.com/pycharm/download/index.html#section=windows 安装完成后在 ...

  9. [雅礼NOIP2018集训 day3]

    考试的时候刚了T1两个小时线段树写了三个子任务结果发现看错了题目,于是接下来一个半小时我自闭了 result=历史新低 这告诉我们,打暴力要端正态度,尤其是在发现自己之前出锅的情况下要保持心态的平和, ...

  10. SSIS获取Oracle数据库数据

    获取Oracle数据库步骤如下: 1.目标服务器获取连接Oracle数据库权限2.安装Oracle客户端,名称为win32_11gR2_client 安装管理员版本的.3.将配置文件tnsnames. ...