九野的博客,转载请注明出处 http://blog.csdn.net/acmmmm/article/details/10966383

开始建图打搓了,参考了大牛的题解打的版本比较清爽,后来改的基本雷同了http://www.cnblogs.com/woaishizhan/archive/2013/04/08/3008719.html

题意:给定n,m表示下面地图大小

.表示空地 #表示墙 *表示黄金

行走的路线是A->Z->a->z

规则,必须从字母依次走最短路到下一个字母(字母必须连续走,如果走不到下一个字母或者地图上不存在下一个字母则输出-1)

每次走到下一个字母可以取走路途上的一个黄金,问最多能取走几个黄金

思路:走到最后一个字母就结束了,所以希望从每个字母走出来都能得到一个黄金,所以是二分匹配

把起点字母作为X集, 黄金作为Y集, 映射条件是黄金在 字母间行走的最短路上

然后这里用BFS寻找路径建图

最后套个二分匹配的模版

#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<math.h>
#include<string.h>
#include<queue>
#include<vector>
#define N 105
#define inf 999999999
using namespace std;
int n,M;
int road[N],p[N*N],gold[N*N],num,pn;//road 表示字母在p中的编号,p是字母的坐标(一维化)
int dis[N][N*N];//dis[a][b] 表示离散化的字母点a到 一维化的坐标b的距离
char map[N][N];
vector<int>G[N]; int go[4][2]={1,0,0,1,-1,0,0,-1};
void bfs(int s){
bool vis[N*N];
memset(vis,0,sizeof(vis));
queue<int>q; memset(dis[s],-1,sizeof(dis[s]));
dis[s][p[s]]=0; q.push(p[s]);
vis[p[s]]=1;
while(!q.empty())
{
int t=q.front();
int x=t/M,y=t%M;
q.pop() ;
for(int i=0;i<4;i++)
{
int nowx=x+go[i][0],nowy=y+go[i][1];
int now=nowx*M+nowy;
if(map[nowx][nowy]=='#')continue;
if(nowx<0 || nowx>=n ||nowy<0||nowy>=M)continue;
if(vis[now])continue;
vis[now]=1; dis[s][now]=dis[s][t]+1;
q.push(now);
}
}
}
int lef[N*N];//lef[v]表示右边点v 当前连接的点
bool T[N*N];//右边的点是否连过 bool match(int x)
{
for(int i=0;i<G[x].size();i++)
{
int v=G[x][i];
if(!T[v])
{
T[v]=true;
if(lef[v]==-1||match(lef[v]))
{
lef[v]=x;
return true;
}
}
}
return false;
} void solve()
{
int ans=0;
memset(lef,-1,sizeof(lef));
for(int i=0;i<pn-1;i++)//左右点集匹配,左点集是 0-(pn-1) 右点集是G[左点].size()
{
memset(T,0,sizeof(T)); if(match(i))ans++;
}
printf("%d\n",ans);
} int f(char c){
if('A'<=c && c<='Z')return c-'A';
else if('a'<=c && c<='z')return c-'a'+26;
}
int main(){
int i,j;
while(~scanf("%d%d",&n,&M)){
pn=num=0;
memset(road,-1,sizeof(road));//这句没有最后第二个案例过不了
for(i=0;i<n;i++)
{
scanf("%s",map[i]);
for(j=0;j<M;j++)
if(isalpha(map[i][j]))
{
p[pn]=i*M+j;
road[f(map[i][j])]=pn;
pn++;
}
else if(map[i][j]=='*')
{
gold[num++]=i*M+j;
}
} for(i=0;i<pn;i++)bfs(i),G[i].clear();
for(i=0;i<pn-1;i++)
{
if(road[i]==-1||road[i+1]==-1) break;
if(dis[road[i]][p[road[i+1]]]==-1) break;
}
if(i!=pn-1){puts("-1");continue;}
for(i=0;i<pn-1;i++)
for(j=0;j<num;j++)
{
if(dis[road[i]][gold[j]]==-1 || dis[road[i+1]][gold[j]]==-1)continue;//j这点的黄金到不了字母点
if(dis[road[i]][gold[j]]+dis[road[i+1]][gold[j]]==dis[road[i]][p[road[i+1]]])
G[i].push_back(j);
}
solve();
}
return 0;
}
/*
3 4
A#B.
***C
.D.. 4 4
A#B.
***C
.D..
..E* 4 4
A#B.
***C
.D..
.*E* 4 4
A#B.
***C
.D#.
.#E* 4 4
A#B.
***C
.D#.
.#E. 4 4
A#B.
***C
.D##
.#E. 4 4
A#B.
***C
.D#*
.#E. 4 4
a#b.
***c
.d#*
.#e. 4 4
A#B*
*.*C
..D#
E*.. ans;
3
3
4
4
3
-1
4
-1
4 */

HDU 3468 BFS+二分匹配的更多相关文章

  1. hdu 1281棋盘游戏(二分匹配)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1281   Problem Description 小希和Gardon在玩一个游戏:对一个N*M的棋盘, ...

  2. poj 3057(bfs+二分匹配)

    题目链接:http://poj.org/problem?id=3057 题目大概意思是有一块区域组成的房间,房间的边缘有门和墙壁,'X'代表墙壁,'D'代表门,房间内部的' . '代表空区域,每个空区 ...

  3. HDU 2819 Swap (二分匹配+破输出)

    题意:给定上一个01矩阵,让你变成一个对角全是 1 的矩阵. 析:二分匹配,把行和列看成两个集合,用匈牙利算法就可以解决,主要是在输出解,在比赛时一紧张不知道怎么输出了. 输出应该是要把 match[ ...

  4. hdu 3681(bfs+二分+状压dp判断)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3681 思路:机器人从出发点出发要求走过所有的Y,因为点很少,所以就能想到经典的TSP问题.首先bfs预 ...

  5. hdu 2119 Matrix(二分匹配)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2119 Matrix Time Limit: 5000/1000 MS (Java/Others)    ...

  6. hdu 1281 棋盘游戏 (二分匹配)

    棋盘游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  7. HDU 2819 — Swap 二分匹配

    Swap Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  8. Fire Net HDU - 1045(二分匹配)

    把每一列中相邻的 .  缩为一个点 作为二分图的左边 把每一行中相邻的  .  缩为一个点 作为二分图的右边 然后求最大匹配即可 这题用匈牙利足够了...然而..我用了hk...有点大材小用的感觉// ...

  9. Hdu 1498 二分匹配

    50 years, 50 colors Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

随机推荐

  1. EAN-13 条码(又称GTIN-13 条码)

    EAN全名为European Article Number(欧洲商品条码),在1977年时由欧洲几个主要工业国家共同发展出来的,后来变成国际商品条码系统.台湾在1985年加入EAN会员,现在我们买东西 ...

  2. 英文:known good board ( KGB) / 中文:测试用标准板,黄金板

    作为标准部件提供的.完全符合设计电气性能的在制板,可以作为与其它印制板比较的标准.

  3. setuptools,easy_install使用

    当需要安装第三方python包时,可能会用到easy_install命令.easy_install是由PEAK(Python Enterprise Application Kit)开发的setupto ...

  4. cmake 学习笔记(四)

    接前面的一二三,学习一下 CMakeCache.txt 相关的东西. CMakeCache.txt 可以将其想象成一个配置文件(在Unix环境下,我们可以认为它等价于传递给configure的参数). ...

  5. Uva 11694 Gokigen Naname

    基本思路是Dfs: 1. 一个一个格子摆放,以每个各自的左上角的点为基准点代表格子,比如(0,0)代表(0,0)(0,1)(1,0)(1,1)组成的格子,(0,1)代表(0,1)(0,2)(1,1), ...

  6. java学习——入门扫盲篇

    概要 近期这几天開始进入java的学习,接触到了好多不是非常了解的概念,像JDK.JRE.JVM.GC等等这些,放到这里来进行下扫盲. java java是一种面向对象程序设计语言和java平台的总称 ...

  7. c++中的对象引用(object reference)与对象指针的区别

    ★ 相同点: 1. 都是地址的概念: 指针指向一块内存,它的内容是所指内存的地址:引用是某块内存的别名. ★ 区别: 1. 指针是一个实体,而引用仅是个别名: 2. 引用使用时无需解引用(*),指针需 ...

  8. python中的class

    尽管Python在Function Programming中有着其他语言难以企及的的优势,但是我们也不要忘了Python也是一门OO语言哦.因此我们关注Python在FP上的优势的同时,还得了解一下P ...

  9. Android 启动APP时黑屏白屏的三个解决方案(转载)

    你会很奇怪,为什么有些app启动时,会出现一会儿的黑屏或者白屏才进入Activity的界面显示,但是有些app却不会如QQ手机端,的确这里要做处理一下.这里先了解一下为什么会出现这样的现象,其实很简单 ...

  10. ThinkPHP - 关联模型 - 多对多

    表结构: 映射关系: UserRelationModel会取UserRelation为表名称.所以要自定义表名称: //定义主表名称protected $tableName = 'User'; < ...