求迷宫的最短路径条数有多少条,一般方法会超时,这里记录一下模板
简要思路:用 a n s ans ans记录到每个点的条数,当新到达的点的新距离小于就旧的距离时,更新新点的 a n s ans ans;若新距离等于旧距离,也就是可能是最短路径的时候,就 a n s 新 + = a n s 旧 ans_{新} += ans_{旧} ans新+=ans旧
P S : PS: PS:若新旧距离相等,则不需要再将该点加入到队列中,因为这个点已经在队列里了
#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() ;
}
}