首页 > 代码库 > HDU 4771 Stealing Harry Potter's Precious

HDU 4771 Stealing Harry Potter's Precious

http://acm.hdu.edu.cn/showproblem.php?pid=4771

 

题意:

给定一副NxM的地图, ‘#‘不可走, ‘.‘可走, ‘@‘为起点

再给出K个(0<K<=4)宝藏点

问从起点开始,走过所有宝藏点的最小步数

若有宝藏点不能到达则输出-1

 

解法:

bfs(最小步数) + dfs(顺序)

bfs预处理,先从起点开始,若有点无法到达直接输出-1

再枚举宝藏点作为起点求出每两点间的最小步数,存入数组中(step[i][j]表示从i点到j点的最小步数)

最后dfs枚举到达宝藏点的顺序,取最小总步数

复杂度; bfs为O(K*N*M) dfs为O(K^2) 但K最大才4

 

代码:  0MS  1220K

#include <iostream>#include <algorithm>#include <cstring>#include <queue>using namespace std;#define _ ios_base::sync_with_stdio(0);cin.tie(0)#define N 101#define judge(x,y) (x>=0&&x<h&&y>=0&&y<w)struct Node {    int x, y, num, step;} pos[5];  //各点信息char map[N][N];  //地图bool flag, vis[N][N], pvis[5];  //是否全可到达, 是否到过该点, 是否已取该宝藏int step[5][5];  //两点间最小步数int h, w, tot, ans, mov[4][2] = { -1, 0, 0, 1, 1, 0, 0, -1};void bfs(Node c) {  //起点    int cnt = 0;    flag = 0;    Node t, p;    queue<Node> que;    que.push(c);    while (!que.empty()) {        p = que.front();        que.pop();        for (int d = 0; d < 4; ++d) {            t.x = p.x + mov[d][0];            t.y = p.y + mov[d][1];            t.step = p.step + 1;            if (judge(t.x, t.y) && !vis[t.x][t.y] && map[t.x][t.y] != #) {                vis[t.x][t.y] = 1;                if (map[t.x][t.y] == $) {                    ++cnt;                    int i;                    for (i = 1; i <= tot && (pos[i].x != t.x || pos[i].y != t.y); ++i);                    step[c.num][i] = step[i][c.num] = min(step[c.num][i], t.step);                }                que.push(t);            }        }    }    if (cnt == tot) {  //全可到达        flag = 1;    }}void dfs(int n, int len, int pre) {  //已取宝藏数,已走步数,前一个宝藏编号    if (n == tot) {        ans = min(ans, len);        return;    }    for (int i = 1; i <= tot; ++i)        if (!pvis[i]) {            pvis[i] = 1;            dfs(n + 1, len + step[pre][i], i);            pvis[i] = 0;        }}int main() {    _;    while (cin >> h >> w && w && h) {        memset(pos, 0, sizeof(pos));        memset(step, 0x7f, sizeof(step));        memset(vis, 0, sizeof(vis));        memset(pvis, 0, sizeof(pvis));        ans = 0xffffff;        for (int i = 0; i < h; ++i) {            cin >> map[i];            for (int j = 0; j < w; ++j)                if (map[i][j] == @) {  //起点存在pos[0]                    pos[0].x = i;                    pos[0].y = j;                    vis[i][j] = 1;                }        }        cin >> tot;        for (int x, y, i = 1; i <= tot; ++i) {  //宝藏点存在pos[1,...,4]            cin >> x >> y;            map[x - 1][y - 1] = $;  //改为‘$‘方便判断            pos[i].x = x - 1;            pos[i].y = y - 1;            pos[i].num = i;        }        bfs(pos[0]);        if (flag) {            for (int i = 1; i <= tot; ++i) {  //枚举起点                memset(vis, 0, sizeof(vis));                vis[pos[i].x][pos[i].y] = 1;                bfs(pos[i]);            }            dfs(0, 0, 0);  //从起点开始dfs            cout << ans << endl;        }        else {            cout << -1 << endl;        }    }    return 0;}

 

HDU 4771 Stealing Harry Potter's Precious