博客
关于我
Codeforces - 1520G-G. To Go Or Not To Go?(全图传送门bfs)
阅读量:406 次
发布时间:2019-03-06

本文共 2982 字,大约阅读时间需要 9 分钟。

 

 

 题目思路:

其实多传送门可以看作几个特殊点,因为特殊点的个数比较少,可以从这些特殊点着手

这个题的传送门位置扩大到了全图位置,而且数量上也没有限制

这个题的传送门最多使用一次

假设如果我在ABCD四个点使用两次传送门

分别为A-B,C-D

那么代价为A+B+C+D

所以不如直接A-D

代价为A-D

具体操作:

可以预处理出每个点距离起点和终点的距离,然后可以算出不使用传送门的代价

然后每个点加上自身的权值,代表如果在此处使用传送门,然后找两个最小的就ok了

这里找最小的时候

CODE:

// Problem: G. To Go Or Not To Go?// Contest: Codeforces - Codeforces Round #719 (Div. 3)// URL: https://codeforces.com/contest/1520/problem/G// Memory Limit: 512 MB// Time Limit: 3000 ms//// Powered by CP Editor (https://cpeditor.org)#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;typedef long long ll;typedef pair
PII;typedef unsigned long long ull;const int inf = 0x3f3f3f3f;const long long INF = 1e18;const int maxn = 2e3 + 7;const ll mod = 1e9 + 7;#define pb push_back#define debug(x) cout << #x << ":" << x << endl;#define mst(x, a) memset(x, a, sizeof(x))#define rep(i, a, b) for (int i = (a); i <= (b); ++i)#define dep(i, a, b) for (int i = (a); i >= (b); --i)inline ll read() { ll x = 0; bool f = 0; char ch = getchar(); while (ch < '0' || '9' < ch) f |= ch == '-', ch = getchar(); while ('0' <= ch && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return f ? -x : x;}void out(ll x) { int stackk[20]; if (x < 0) { putchar('-'); x = -x; } if (!x) { putchar('0'); return; } int top = 0; while (x) stackk[++top] = x % 10, x /= 10; while (top) putchar(stackk[top--] + '0');}ll qpow(ll a, ll b) { ll ans = 1; while (b) { if (b & 1) ans = ans * a % mod; a = a * a % mod; b >>= 1; } return ans;}ll vis[maxn][maxn], n, m, w;ll d1[maxn][maxn], d2[maxn][maxn];ll a[maxn][maxn];ll dx[4] = {1, 0, -1, 0};ll dy[4] = {0, 1, 0, -1};ll b[maxn * maxn];void bfs(ll x, ll y, ll d[][maxn]) { queue
q; mst(vis, 0); vis[x][y] = 1; q.push({x, y}); d[x][y] = 0; while (q.size()) { auto fr = q.front(); q.pop(); int x1 = fr.first; int y1 = fr.second; for (int i = 0; i < 4; i++) { int x2 = x1 + dx[i]; int y2 = y1 + dy[i]; if (x2 < 1 || x2 > n || y2 < 1 || y2 > m) continue; if (a[x2][y2] == -1) continue; if (vis[x2][y2] == 0) { vis[x2][y2] = 1; d[x2][y2] = d[x1][y1] + w; q.push({x2, y2}); } } }}ll c[maxn * maxn];int main() { // ios::sync_with_stdio(false); n = read(), m = read(), w = read(); int cnt = 0; mst(d1, -1); mst(d2, -1); rep(i, 1, n) rep(j, 1, m) a[i][j] = read(); bfs(1, 1, d1), bfs(n, m, d2); ll ans = 1e18; ll res = 0; rep(i, 1, n) rep(j, 1, m) if (a[i][j] >= 0 && d1[i][j] >= 0 && d2[i][j] >= 0) ans = min(ans, d1[i][j] + d2[i][j]); for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if (a[i][j] > 0) { if (a[i][j] > 0 && d1[i][j] >= 0) b[++cnt] = d1[i][j] + a[i][j]; if (a[i][j] > 0 && d2[i][j] >= 0) c[++res] = d2[i][j] + a[i][j]; } } } sort(b + 1, b + 1 + cnt),sort(c + 1, c + 1 + res); if (cnt && res)ans = min(ans, b[1] + c[1]); if (ans > 1e17)puts("-1"); else out(ans); return 0;}/**/
View Code

 

转载地址:http://vadkz.baihongyu.com/

你可能感兴趣的文章
MySQL 的全局锁、表锁和行锁
查看>>
mysql 的存储引擎介绍
查看>>
MySQL 的存储引擎有哪些?为什么常用InnoDB?
查看>>
Mysql 知识回顾总结-索引
查看>>
Mysql 笔记
查看>>
MySQL 精选 60 道面试题(含答案)
查看>>
mysql 索引
查看>>
MySQL 索引失效的 15 种场景!
查看>>
MySQL 索引深入解析及优化策略
查看>>
MySQL 索引的面试题总结
查看>>
mysql 索引类型以及创建
查看>>
MySQL 索引连环问题,你能答对几个?
查看>>
Mysql 索引问题集锦
查看>>
Mysql 纵表转换为横表
查看>>
mysql 编译安装 window篇
查看>>
mysql 网络目录_联机目录数据库
查看>>
MySQL 聚簇索引&&二级索引&&辅助索引
查看>>
Mysql 脏页 脏读 脏数据
查看>>
mysql 自增id和UUID做主键性能分析,及最优方案
查看>>
Mysql 自定义函数
查看>>