//给一个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. jsonp实现原理

    jquery 封装在 ajax方法 里面的jsonp jsonp跨域的原理       1:使用script 标签发送请求,这个标签支持跨域访问       2:在script 标签里面给服务器端传递 ...

  2. Android仿QQ ios dialog,仿QQ退出向上菜单

    Android仿QQ ios dialog,仿QQ退出向上菜单 EasyDialog两种模式 仿QQ退出向上菜单,自己定义向上菜单              github地址:https://gith ...

  3. codeforces7D Palindrome Degree(manacher&amp;dp或Hsh&amp;dp)

    D. Palindrome Degree time limit per test 1 second memory limit per test 256 megabytes input standard ...

  4. HDOJ 5294 Tricks Device 最短路(记录路径)+最小割

    最短路记录路径,同一时候求出最短的路径上最少要有多少条边, 然后用在最短路上的边又一次构图后求最小割. Tricks Device Time Limit: 2000/1000 MS (Java/Oth ...

  5. 博客迁移到reetsee.com

    正如上一篇博客所言.眼下CSDN的博客已经基本完毕它的使命了.感谢CSDN带给我的全部美好回顾. 如今我想尝试一下自己维护一个博客,所以博客的全部内容都迁移到了reetsee.com. 以后博客更新会 ...

  6. 数据挖掘算法学习(四)PCA算法

    转载请附上链接http://blog.csdn.net/iemyxie/article/details/38236647 算法简单介绍 主成分分析(PrincipalComponentAnalysis ...

  7. 朝花夕拾——finally/final/finalize拨云雾见青天

    Java编程中.常常会使用到异常处理,而finally看似的是try/catch后对逻辑处理的完好,事实上里面却存在非常多隐晦的陷阱.final常见于变量修饰,那么你在内部类中也见过吧.finaliz ...

  8. ES shard unassigned的解决方法汇总

    说下shard出现的几个状态说明: relocating_shards shows the number of shards that are currently moving from one no ...

  9. DB-MySQL:MySQL 函数

    ylbtech-DB-MySQL:MySQL 函数 1. MySQL 字符串函数返回顶部 1. MySQL 字符串函数 函数 描述 实例 ASCII(s) 返回字符串 s 的第一个字符的 ASCII ...

  10. 90.bower解决js的依赖管理

    转自:https://blog.csdn.net/u011537073/article/details/52951122 前言一个新的web项目开始,我们总是很自然地去下载需要用到的js类库文件,比如 ...