[USACO11OPEN] Corn Maze S - 最短路
Posted mollnn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[USACO11OPEN] Corn Maze S - 最短路相关的知识,希望对你有一定的参考价值。
给定一个 (N imes M) 地图,每个格子可能是空地、墙、出口、起点,或者是一副瞬移管道的两端。当你达到瞬移管道一端所在的格子时,就会自动瞬移到另一端。从一个空地移到四连通的另一个空地需要 (1) 时间。瞬移不需要时间。求从起点到出口的最小时间。(N leq 300, M leq 300)
Solution
难度:L3
拆点建图跑最短路即可
每个点拆成入点和出点,其中普通点的入点和出点直接相连,瞬移管道的入点和出点不想连,管道一端的入点连到管道另一端的出点,费用为 (0)
#include <bits/stdc++.h>
#define reset3f(x) memset(x,0x3f,sizeof x)
using namespace std;
namespace sp {
const int N=4e+6+5;
vector<pair<int,int> > g[N];
int v0=1,d[N];
void make(int t1,int t2,int t3) {
g[t1].push_back(make_pair(t2,t3));
}
void solve() {
priority_queue<pair<int,int> > qu;
reset3f(d);
d[v0]=0;
qu.push(make_pair(0,v0));
while(qu.size()) {
int p=qu.top().second,r=qu.top().first;
qu.pop();
if(r+d[p]) continue;
for(int i=0;i<g[p].size();i++) {
int q=g[p][i].first,w=g[p][i].second;
if(d[q]>d[p]+w) {
d[q]=d[p]+w;
qu.push(make_pair(-d[q],q));
}
}
}
}
}
using sp::make;
using sp::solve;
using sp::d;
using sp::v0;
const int N = 305;
const int dx[4] = {-1,1,0,0};
const int dy[4] = {0,0,1,-1};
int n,m;
char s[N][N];
int id(int i,int j) {
return m*(i-1)+j;
}
int idx(int i,int j) {
return m*n+m*(i-1)+j;
}
int ok(int i,int j) {
return i>0 && j>0 && i<=n && j<=m && s[i][j]!='#';
//(s[i][j]=='.' || s[i][j]=='@' || s[i][j]=='=');
}
int r1[27],c1[27],r2[27],c2[27];
signed main() {
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>s[i]+1;
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
if(ok(i,j)) {
if(s[i][j]<'A' || s[i][j]>'Z')
make(id(i,j),idx(i,j),0);
if(ok(i-1,j)) make(idx(i,j),id(i-1,j),1);
if(ok(i+1,j)) make(idx(i,j),id(i+1,j),1);
if(ok(i,j-1)) make(idx(i,j),id(i,j-1),1);
if(ok(i,j+1)) make(idx(i,j),id(i,j+1),1);
}
if(s[i][j]>='A' && s[i][j]<='Z') {
if(r1[s[i][j]-'A']==0) {
r1[s[i][j]-'A']=r2[s[i][j]-'A']=i;
c1[s[i][j]-'A']=c2[s[i][j]-'A']=j;
}
else {
r2[s[i][j]-'A']=i;
c2[s[i][j]-'A']=j;
}
}
}
}
for(int i=0;i<26;i++) {
if(r1[i]) {
make(id(r1[i],c1[i]),idx(r2[i],c2[i]),0);
make(id(r2[i],c2[i]),idx(r1[i],c1[i]),0);
}
}
int i1,j1,i2,j2;
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
if(s[i][j]=='@') i1=i,j1=j;
if(s[i][j]=='=') i2=i,j2=j;
}
}
v0=id(i1,j1);
solve();
cout<<d[id(i2,j2)];
}
以上是关于[USACO11OPEN] Corn Maze S - 最短路的主要内容,如果未能解决你的问题,请参考以下文章
洛谷 P1825 [USACO11OPEN]玉米田迷宫Corn Maze
luogu P1825 [USACO11OPEN]玉米田迷宫Corn Maze 题解