hdu 2824 Dogs(BFS, 优先队列优化)

来源:互联网 发布:联通3g拨号软件 编辑:程序博客网 时间:2024/06/03 10:13

BFS加速的两个方法:记忆化,优先队列,剪枝

记忆化:开一个 int 型数组记录访问某点的时间

优先队列:将更优的结果放到前面,这样在一次搜索到结束态的时候便可以退出

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <string>#include <vector>#include <queue>using namespace std;#define REP(i,s,t) for(int (i)=(s);(i)<=(t);++(i))#define INF 0x7FFFFFFFtypedef long long LL;typedef pair<int, int> pairi;const int maxn = 1000;int n, m, idx;char a[maxn+5][maxn+5];int b[maxn+5][maxn+5];int vis[maxn+5][maxn+5];const int dx[4] = {1, -1, 0, 0};const int dy[4] = {0, 0, 1, -1};vector<int> adj[maxn*maxn+5];pairi src, dst;struct node {    int x;int y;int v;};class mycmp{public:    bool operator () (const node&lhs, const node&rhs) const {        return lhs.v > rhs.v;    }};int main() {    freopen("input.in", "r", stdin);    char buf[1500];    while (scanf("%d%d",&n,&m) && (n|m)) {        REP(i, 0, n-1) {            scanf("%s",a[i]);        }        scanf("%d%d%d%d",&src.first, &src.second, &dst.first, &dst.second);        --src.first;--src.second;--dst.first;--dst.second;        memset(b, -1, sizeof(b));        idx = 0;        adj[0].clear();        REP(i, 0, n-1)            REP(j, 0, m-1)                if (a[i][j] == 'X' && b[i][j] == -1) {                    queue<node> q;                    q.push((node){i, j, 0});                    b[i][j] = idx;                    while (q.empty() == false) {                        node fr = q.front();q.pop();                        int x = fr.x, y = fr.y;                        REP(i, 0, 3) {                            int to_x = x + dx[i], to_y = y + dy[i];                            if (to_x < 0 || to_x >= n || to_y < 0 || to_y >= m) continue;                            if (a[to_x][to_y] == '.')                                adj[idx].push_back(to_x*1000+to_y);                            else if (b[to_x][to_y] == -1) {                                b[to_x][to_y] = idx;                                q.push((node){to_x, to_y});                            }                        }                    }                    ++idx;                    adj[idx].clear();                }        REP(i, 0, n-1)            REP(j, 0, m-1)                vis[i][j] = INF;        priority_queue<node, std::vector<node>, mycmp> q;        int dst_id = b[dst.first][dst.second];        int _min = INF;        int is_find = 0;        q.push((node){src.first, src.second, 0});        while (!q.empty() && !is_find) {            node fr = q.top();q.pop();            //cout << fr.x << ' ' << fr.y << ' ' << fr.v << endl;            int x = fr.x, y = fr.y, v = fr.v;            if (a[x][y] == '.') {                REP(i, 0, 3) {                    int to_x = x + dx[i], to_y = y + dy[i], to_v;                    if (0<=x&&x<n&&0<=y&&y<m) {                        if (a[to_x][to_y] == 'X')                            to_v = v;                        else                            to_v = v+1;                        if (to_v < _min && to_v < vis[to_x][to_y]) {                            vis[to_x][to_y] = to_v;                            if (to_x == dst.first && to_y == dst.second) {                                _min = to_v;                                ++is_find;                            }                            else                                q.push((node){to_x, to_y, to_v});                        }                    }                }            }            else {                int id = b[x][y];                if (id == dst_id) {                    int to_x = dst.first, to_y = dst.second;                    if (v<vis[to_x][to_y]) {                        vis[to_x][to_y] = v;                        _min = v;                    }                    ++is_find;                    continue;                }                int sz = adj[id].size();                REP(i, 0, sz-1) {                    int tmp = adj[id][i];                    int to_x = tmp/1000, to_y = tmp%1000, to_v = v+1;                    if (to_v < _min && to_v<vis[to_x][to_y]) {                        vis[to_x][to_y] = to_v;                        q.push((node){to_x, to_y, to_v});                    }                }            }        }        cout << _min << endl;#ifdef DEBUG        REP(i, 0, idx) {            int sz = adj[i].size();            REP(j, 0, sz-1) {                int v = adj[i][j];                int x = v/1000, y = v%1000;                b[x][y] = 6;            }        }        REP(i, 0, n-1) {            REP(j, 0, m-1) {                if (b[i][j] >= 0)                    cout << ' ' << b[i][j] << ' ';                else                    cout << b[i][j] << ' ';            }            cout << endl;        }#endif    }    return 0;}


0 0
原创粉丝点击