迷宮問題——最短路徑條數
阿新 • • 發佈:2018-11-16
求迷宮的最短路徑條數有多少條,一般方法會超時,這裡記錄一下模板
簡要思路:用 記錄到每個點的條數,當新到達的點的新距離小於就舊的距離時,更新新點的 ;若新距離等於舊距離,也就是可能是最短路徑的時候,就
若新舊距離相等,則不需要再將該點加入到佇列中,因為這個點已經在佇列裡了
優先佇列:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll mod = 1000000007;
int dx[4] = {0,1,0,-1};
int dy[4] = {1,0,-1,0};
int r, c, edx, edy;
int dis[505][505], maze[505][505];
char mp[505][505];
ll ans[505][505];
bool vis[505][505];
struct Point {
int x, y, t;
bool operator<(const Point & b) const {
return t>b.t;
}
Point(){}
Point(int x,int y,int t):x(x),y(y),t(t) {}
} p;
void BFS() {
dis[1][1] = 0;
ans[1][1] = 1;
priority_queue <Point> pq;
pq.push(Point(1,1,0));
while(!pq.empty()) {
int nx, ny;
//找點
Point cur = pq.top(); pq.pop();
if(vis[cur.x][cur.y] == 1) continue;
vis[cur.x][cur.y] = 1;
for(int k=0; k<4; k++) {
nx = cur.x + dx[k];
ny = cur.y + dy[k];
if(vis[nx][ny] == 1) continue;
if(nx<1 || nx>r || ny<1 || ny>c) continue;
int t = dis[cur.x][cur.y] + maze[nx][ny];
if(dis[nx][ny] > t) {
dis[nx][ny] = t;
ans[nx][ny] = ans[cur.x][cur.y]%mod;
pq.push(Point(nx, ny, dis[nx][ny]));
}
else if(dis[nx][ny] == t) {
ans[nx][ny] += ans[cur.x][cur.y];
ans[nx][ny] %= mod;
//pq.push(Point(nx, ny, dis[nx][ny]));
}
}
}
if(dis[edx][edy] == INF) printf("-1\n");
else printf("%lld\n", ans[edx][edy]%mod);
}
void init() {
memset(vis,0,sizeof(vis));
memset(ans,0,sizeof ans);
memset(maze,INF,sizeof(maze));
memset(dis,INF,sizeof(dis));
}
int main(){
int cas;
scanf("%d", &cas);
while(cas--) {
scanf("%d%d", &r, &c);
init();
for(int i=1; i<=r; i++)
scanf("%s", mp[i]+1);
for(int i=1; i<=r; i++)
for(int j=1; j<=c; j++)
if(mp[i][j] == '.')
maze[i][j] = 1;
scanf("%d%d", &edx, &edy);
BFS() ;
}
}