1. 程式人生 > >迷宮問題——最短路徑條數

迷宮問題——最短路徑條數

    求迷宮的最短路徑條數有多少條,一般方法會超時,這裡記錄一下模板

    簡要思路:用 a n s ans 記錄到每個點的條數,當新到達的點的新距離小於就舊的距離時,更新新點的 a

n s ans ;若新距離等於舊距離,也就是可能是最短路徑的時候,就 a n s +
= a n s ans_{新} += ans_{舊}

     P

S 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() ;
    }
}