POJ-3026(Borg Maze) BFS + MST

15 篇文章 0 订阅
12 篇文章 0 订阅

POJ-3026

hint:
此题是最小生成树和BFS的综合题, 需要对输入的数据进行BFS预处理,得到每个点之间的距离, 即可当作简单最小生成树处理, 这里使用Kruskal得到最小生成树。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;

const int SIZE = 60;
const int dist[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
char maze[SIZE][SIZE];
int f[10000];
int cnt;

int getHash(int a, int b){
    return a*100 + b;
}

struct _Edge{
    int from, to, dist;
    _Edge(int _from, int _to, int _dist): from(_from), to(_to), dist(_dist){};
    _Edge(){};
};
_Edge edge[110*119];

struct _Node{
    int x, y, dist;
    _Node(){};
    _Node(int _x, int _y, int _dist): x(_x), y(_y), dist(_dist){};
};

void BFS_GETDIST(_Node beg){
    int visit[SIZE][SIZE];
    memset(visit, 0, sizeof(visit));
    visit[beg.x][beg.y] = 1;
    queue<_Node> q;
    q.push(beg);
    while(!q.empty())
    {
        _Node u = q.front(); q.pop();

        if(maze[u.x][u.y] == 'A' && getHash(beg.x, beg.y) != getHash(u.x, u.y)){
            edge[cnt].from = getHash(beg.x, beg.y);
            edge[cnt].to = getHash(u.x, u.y);
            edge[cnt++].dist = u.dist;
        }
        for(int i = 0; i < 4; ++i)
        {
            int dx = u.x + dist[i][0], dy = u.y + dist[i][1];

            if(maze[dx][dy] != '#' && !visit[dx][dy])
            {
                q.push(_Node(dx, dy, u.dist + 1));
                visit[dx][dy] = 1;
            }
        }
    }
}

bool cmp(_Edge e1, _Edge e2){
    return e1.dist < e2.dist;
}

int find(int x){
    return f[x] == -1 ? x : f[x] = find(f[x]);
}

int Kruskal(int n)
{
    memset(f, -1, sizeof(f));
    sort(edge, edge + cnt, cmp);
    //for(int i = 0; i < cnt; ++i) cout << "from: " << edge[i].from << " to: " << edge[i].to << " dist: " << edge[i].dist << endl;
    int res = 0;
    int p = 0;
    for(int i = 0; i < cnt; ++i){
        int a = find(edge[i].from);
        int b = find(edge[i].to);

        if(a != b){
            f[a] = b;
            p ++;
            res += edge[i].dist;
        }
        if(p == n - 1) break;
    }
    if(p < n - 1) return -1;
    else return res;
}
int main(){
    int t, row, col, n;
    char c;
    cin >> t;
    while(t--){
        scanf("%d%d\n", &row, &col);
        _Node start;
        n = 0;
        for(int i = 0; i < SIZE; ++i)
            for(int j = 0; j < SIZE; ++j) maze[i][j] = '#';
        for(int i = 1; i <= col; i++)
        {
            for(int j = 1; j <= row; ++j)
            {
                c = getchar();
                maze[i][j] = c;
                if(maze[i][j] == 'S'){
                    start.x = i;
                    start.y = j;
                    start.dist = 0;
                    n++;
                }
                if(maze[i][j] == 'A') n++;
            }
            getchar();
        }
        //cout <<"n = " << n << endl;
        cnt = 0;
        for(int i = 1; i <= col; ++i)
            for(int j = 1; j <= row; ++j) if(maze[i][j] == 'S' || maze[i][j] == 'A') BFS_GETDIST(_Node(i, j, 0));

        //for(int i = 0; i < cnt; ++i) cout << "from: " << edge[i].from << " to: " << edge[i].to << " dist: " << edge[i].dist << endl;
        int t = Kruskal(n);
        printf("%d\n", t);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值