http://codeforces.com/gym/100625/attachments/download/3213/2013-benelux-algorithm-programming-contest-bapc-13-en.pdf

题意:给你一幅图,让两个人从里面走出来的代价最小。经过 . 没有消耗,经过 # 耗费一个代价,* 不能通过。

思路:比赛时以为是类似于两条路之和最小的那种题,所以没有仔细去想,下来后听了别人提了下思路,也看了下别人的代码,明白了。分两种情况考虑,一种是相遇,一种是不相遇。如果存在不相遇这种答案的话,那结果就是他们俩的最短路之和,相遇的话,就是他们俩到相遇的地方的最短路之和加上相遇的door到外面的最短路减2。这是陈力琪他们队做的,我也是看了他们的代码。

  所以求三遍最短路,第一遍w[i] 表示i这个点到外面的最小代价。第二遍 ds[i] 表示从s(第一个人位置)到i的最小代价,第三遍 dt[i] 表示从t到i的最短路。按照上面的说法得出答案就可以了。

  比较有意思是这里的搜索,因为 . 是不需要代价的,所以在bfs的时候每下一步就直接dfs一次找到下一个#所在的位置再把代价+1入队。在求w[i]的时候,因为距离可能为0,所以得先把边界上的 . 入队,不然w[i]就会求错。

  

 #pragma comment(linker, "/STACK:1000000000")
#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#define LL long long
#define MAXN 100005
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define eps 1e-8
using namespace std;
char a[][];
int n, m;
int w[], ds[], dt[];
bool vis[][];
vector<int> door;
queue<int> Q;
const int step[][] = { , , , , -, , , - };
void dfs(int x, int y, int d, int *f){
for (int i = ; i < ; i++){
int u = x + step[i][];
int v = y + step[i][];
if (vis[u][v] || a[u][v] == '*' || u < || v < || u >= n || v >= m) continue;
f[m * u + v] = d;
vis[u][v] = true;
if (a[u][v] == '#'){
f[m * u + v]++;
Q.push(m * u + v);
}
else{
dfs(u, v, d, f);
}
}
}
void bfs(int *f){
while (!Q.empty()){
int p = Q.front();
int x = p / m, y = p % m;
Q.pop();
//dfs一次相当于代价加一
dfs(x, y, f[m * x + y], f);
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif // OPEN_FILE
int T;
scanf("%d", &T);
while (T--){
scanf("%d%d", &n, &m);
for (int i = ; i < n; i++){
scanf("%s", &a[i]);
}
memset(w, INF, sizeof(w));
memset(ds, INF, sizeof(ds));
memset(dt, INF, sizeof(dt));
memset(vis, , sizeof(vis));
door.clear();
bool apos = false;
int s = , t = ;
for (int i = ; i < n; i++){
for (int j = ; j < m; j++){
if ((i == || j == || i == n - || j == m - ) && (a[i][j] == '.' || a[i][j] == '$')){
Q.push(m * i + j);
w[m * i + j] = ;
vis[i][j] == true;
}
}
}
for (int i = ; i < n; i++){
for (int j = ; j < m; j++){
if (a[i][j] == '*') continue;
if ((i == || j == || i == n - || j == m - ) && a[i][j] == '#'){
w[m * i + j] = ;
Q.push(m * i + j);
vis[i][j] = true;
}
if (a[i][j] == '#'){
door.push_back(m * i + j);
}
if (a[i][j] == '$'){
if (!apos){
s = m * i + j;
ds[s] = ;
apos = true;
}
else{
t = m * i + j;
dt[t] = ;
}
}
}
}
bfs(w);
memset(vis, , sizeof(vis));
vis[s / m][s % m] = true;
Q.push(s);
bfs(ds);
memset(vis, , sizeof(vis));
vis[t / m][t % m] = true;
Q.push(t);
bfs(dt);
int ans = w[s] + w[t];
for (int i = ; i < door.size(); i++){
ans = min(ans, ds[door[i]] + dt[door[i]] + w[door[i]] - );
}
printf("%d\n", ans);
}
}

Gym - 100625J Jailbreak 最短路+搜索的更多相关文章

  1. UVA 11624 UVA 10047 两道用 BFS进行最短路搜索的题

    很少用bfs进行最短路搜索,实际BFS有时候挺方便得,省去了建图以及复杂度也降低了O(N*M): UVA 11624 写的比较挫 #include <iostream> #include ...

  2. Gym 101873C - Joyride - [最短路变形][优先队列优化Dijkstra]

    题目链接:http://codeforces.com/gym/101873/problem/C 题意: 这是七月的又一个阳光灿烂的日子,你决定和你的小女儿一起度过快乐的一天.因为她真的很喜欢隔壁镇上的 ...

  3. GYM 101933D(最短路、二分、dp)

    要点 非要先来后到暗示多源最短路,求最小的最大值暗示二分 二分内部的check是关键,dp处理一下,\(dp[i]\)表示第\(i\)笔订单最早何时送达,如果在ddl之前到不了则\(return\ 0 ...

  4. GYM 101933E(记忆化搜索)

    用每个人的血量作为状态去搜索T飞,考虑题解中更好的搜索方式:每种血量有多少个人作为状态.这样会减去很多重复的状态,因为只要乘一下就得到了所有相同情况的和. 虽然我不会算,但是直观感受起来复杂度比较优秀 ...

  5. Loppinha, the boy who likes sopinha Gym - 101875E (dp,记忆化搜索)

    https://vjudge.net/contest/299302#problem/E 题意:给出一个01 0101串,然后能量计算是连续的1就按1, 2, 3的能量加起来.然后给出起始的能量,求最少 ...

  6. POJ 1724 ROADS【最短路/搜索/DP】

    一道写法多样的题,很具有启发性. 具体参考:http://www.cnblogs.com/scau20110726/archive/2013/04/28/3050178.html http://blo ...

  7. Gym 101142C CodeCoder vs TopForces (搜索)

    题意:每个人有2种排名,对于A只要有一种排名高于B,那么A就能赢B,再如果B能赢C,那么A也能赢C,要求输出每个人分别能赢多少个人 析:首先把题意先读对了,然后我们可以建立一个图,先按第一种排名排序, ...

  8. Gym - 102141D 通项公式 最短路

    题目很长,但是意思就是给你n,A,B,C,D n表示有n个城市 A是飞机的重量 B是一个常数表示转机代价 C是单位燃油的价格 D是一个常数 假设一个点到另外一个点的距离为整数L 起飞前的油量为f  则 ...

  9. 暑假集训-WHUST 2015 Summer Contest #0.2

    ID Origin Title 10 / 55 Problem A Gym 100625A Administrative Difficulties   4 / 6 Problem B Gym 1006 ...

随机推荐

  1. python基础4(小数据池,编码,深浅拷贝)

    1.==与is == 比较值是否相等 is比较内存地址是否相同 2.小数据池 为了节省内存,当数据在一个范围里的时候,两个值相同的变量指向的是小数据池里的同一个地址 数字范围:-5 ~ 256 num ...

  2. 紫书 例题 10-2 UVa 12169 (暴力枚举)

    就是暴力枚举a, b然后和题目给的数据比较就ok了. 刘汝佳这道题的讲解有点迷,书上讲有x1和a可以算出x2, 但是很明显x2 = (a * x1 +b) 没有b怎么算x2?然后我就思考了很久,最后去 ...

  3. OC中的@的作用研究

    OC中的@字符用的频率很的高,其主要作用是为了差别于其它语言的keyword和语法 以下我们来研究一下其应用 1.声明类,协议,延展,权限,属性等 @interface声明类 @protocol声明协 ...

  4. 陈-朱-兴- js写法【案例】:

    ajax请求: 一.从服务器端请求数据: var url = '';url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='+ ...

  5. hdoj--5256--序列变换(lis变形)

    序列变换 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  6. 解决Linux下yum安装无法解析URL的问题

    问题: [root@yaya ~]# yum -y install gcc-* Loaded plugins: fastestmirror, presto Could not retrieve mir ...

  7. RecordAccumulator 1

    介绍 前面讲过producer会将数据保存在RecordAccumulator中,并通过Sender发送数据.RecordAccumulator 就相当于一个队列保存着那些准备发送到server的数据 ...

  8. HDU I Hate It(线段树单节点更新,求区间最值)

    http://acm.hdu.edu.cn/showproblem.php?pid=1754 Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分 ...

  9. UI Framework-1: Aura Views

    Views Views is a user interface framework built on a type called, confusingly, View. Responsible for ...

  10. HNU 12886 Cracking the Safe 二十四点的判断

    经典的一个题,今天竟然写跪了…… 题意: 给你4个数字,让你判断是否能通过四则运算和括号,凑成24点. 思路: 暴力枚举运算顺序和运算符. 代码: #include <iostream> ...