CodeForces - 1520G To Go Or Not To Go?(bfs)
Posted Frozen_Guardian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces - 1520G To Go Or Not To Go?(bfs)相关的知识,希望对你有一定的参考价值。
题目链接:点击查看
题目大意:给出一个 n ∗ m n*m n∗m 的矩阵,其中:
- − 1 -1 −1:该位置是个墙
- 0 0 0:该位置可以通过
- x ( x > 0 ) x(x>0) x(x>0):该位置是传送门
对于任意两个传送门,可以花费其权值和的代价相互到达
也可以花费 w w w 向上下左右四个方向移动
问从 ( 1 , 1 ) (1,1) (1,1) 到 ( n , m ) (n,m) (n,m) 的最小花费是多少
题目分析:一开始想到了对传送门建一个超级源点,将所有传送门都与超级源点相连然后跑迪杰斯特拉,但是这样就有 1 e 7 1e7 1e7 条边,迪杰斯特拉又是超时又是内存超限
分析一下本题的性质,有一个比较重要的点就是,如果是走传送门的话,肯定只会从一个传送门进去然后从另一个传送门出来,因为假如传送门 A A A 到 B B B 是可行的,那么肯定不会选择 A A A 到 C C C,然后再从 C C C 到 B B B
所以最小花费只有两种情况:
- ( 1 , 1 ) (1,1) (1,1) 不走传送门直接到 ( n , m ) (n,m) (n,m)
- ( 1 , 1 ) (1,1) (1,1) 到传送门 A A A ,传送到 B B B,然后从 B B B 到 ( n , m ) (n,m) (n,m)
基于此,可以用 b f s bfs bfs 计算出所有点到 ( 1 , 1 ) (1,1) (1,1) 的距离和 ( n , m ) (n,m) (n,m) 的距离,然后枚举所有的传送门维护出 A A A 和 B B B 即可
代码:
// #pragma GCC optimize(2)
// #pragma GCC optimize("Ofast","inline","-ffast-math")
// #pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
template<typename T>
inline void read(T &x)
{
T f=1;x=0;
char ch=getchar();
while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
x*=f;
}
template<typename T>
inline void write(T x)
{
if(x<0){x=~(x-1);putchar('-');}
if(x>9)write(x/10);
putchar(x%10+'0');
}
const LL inf=0x3f3f3f3f3f3f3f3f;
const int N=2e3+100;
const int b[4][2]={0,1,0,-1,1,0,-1,0};
int n,m,w;
int maze[N][N];
LL d1[N][N],d2[N][N];
void bfs(int x,int y,LL d[][N]) {
memset(d,-1,sizeof(LL)*(N*N));
queue<pair<int,int>>q;
q.push({x,y});
d[x][y]=0;
while(q.size()) {
int x,y;
tie(x,y)=q.front();
q.pop();
for(int i=0;i<4;i++) {
int xx=x+b[i][0];
int yy=y+b[i][1];
if(xx<=0||xx>n||yy<=0||yy>m) {
continue;
}
if(maze[xx][yy]==-1||d[xx][yy]!=-1) {
continue;
}
d[xx][yy]=d[x][y]+w;
q.push({xx,yy});
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
#endif
// ios::sync_with_stdio(false);
read(n),read(m),read(w);
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
read(maze[i][j]);
}
}
bfs(1,1,d1);
bfs(n,m,d2);
LL ans=inf;
if(d1[n][m]!=-1) {
ans=min(ans,d1[n][m]);
}
LL res1=inf,res2=inf;
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
if(maze[i][j]>0) {
if(d1[i][j]!=-1) {
res1=min(res1,d1[i][j]+maze[i][j]);
}
if(d2[i][j]!=-1) {
res2=min(res2,d2[i][j]+maze[i][j]);
}
}
}
}
ans=min(ans,res1+res2);
if(ans==inf) {
puts("-1");
return 0;
}
write(ans);
return 0;
}
以上是关于CodeForces - 1520G To Go Or Not To Go?(bfs)的主要内容,如果未能解决你的问题,请参考以下文章
codeforces 868A Bark to Unlock
Codeforces 868A Bark to Unlock
#3 Codeforces-865C Gotta Go Fast(期望dp)