码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 4771 Stealing Harry Potter's Precious

时间:2015-02-01 21:39:15      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:

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

标签:

原文地址:http://www.cnblogs.com/rsola/p/4266036.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!