//给一个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. Node.js 指南(迁移到安全的Buffer构造函数)

    迁移到安全的Buffer构造函数 移植到Buffer.from()/Buffer.alloc() API. 概述 本指南介绍了如何迁移到安全的Buffer构造函数方法,迁移修复了以下弃用警告: 由于安 ...

  2. React:关于虚拟DOM(Virtual DOM)

    Virtual DOM 是一个模拟 DOM 树的 JavaScript 对象. React 使用 Virtual DOM 来渲染 UI,当组件状态 state 有更改的时候,React 会自动调用组件 ...

  3. 【codeforces 734F】Anton and School

    [题目链接]:http://codeforces.com/problemset/problem/734/F [题意] 给你两个数组b和c; 然后让你找出一个非负数组a满足题中所给关系; [题解] 有个 ...

  4. [SCSS] Pure CSS for multiline truncation with ellipsis

    1. Pure CSS 2. Responsive 3. No need to recalculate on resize or font’s load event 4. Cross browser

  5. [Python Test] Use pytest fixtures to reduce duplicated code across unit tests

    In this lesson, you will learn how to implement pytest fixtures. Many unit tests have the same resou ...

  6. php给图片加入文字水印

    PHP对图片的操作用到GD库.这里我们介绍怎样给图片加入文字水印. 大致分为四步: 1.打开图片 2.操作图片 3.输出图片 4.销毁图片 以下我们上代码来详细解说每步的实现过程: <? php ...

  7. lua简单类的实现

    原文地址:http://blog.csdn.net/qqmcy/article/details/37725177 类实现: MyClass = class("MyClass") - ...

  8. cmd 下命令

    tasklist 查看当前进程 taskkill /? 查看taskkill 的帮助信息 详情 cmd /?  查看cmd详情 color /? 查看颜色详情  比如 color 2 md d:\ji ...

  9. 【VC++游戏开发】智力游戏——鸡蛋里挑骨头(仿扫雷)

    在我学习游戏开发的过程中,遇到的最大的麻烦就是不知道一个游戏的完整实现过程,代码倒是其次. 这里,总结一下我做过的游戏.主要是梳理整每一个步骤. 先看下终于的效果 第1步,准备素材图片 包含鸡蛋.骨头 ...

  10. _00017 Kafka的体系结构介绍以及Kafka入门案例(0基础案例+Java API的使用)

    博文作者:妳那伊抹微笑 itdog8 地址链接 : http://www.itdog8.com(个人链接) 博客地址:http://blog.csdn.net/u012185296 博文标题:_000 ...