POJ 3026 Borg Maze【prim + BFS】

题目链接:http://poj.org/problem?id=3026

题意:

外星人从S出发去寻找A,外星人只有在两种情况下才会分成多组,同时去寻找其他外星人,第一种情况是从S出发的时候会分成多组,第二种是在找到A的情况下分成多组;分成的多组外星人中可以让多组同时走,也可以让某几个不走,留在原地,计算的总距离就是移动过的外星人走过的路得总和;比如说  一个A的左边2个单位有一个A,右边3个单位有一个A,那么我们可以分成两组,一左一右,左边走两步,右边走三步,那么步数就是3+2;还有一种情况就是, A只有左边有一个A,那么你可以不分组(题目说至少分二个,但是分出来的那个你可以让它留在原地不走)直接往左走;(注意:分组过后的步数是从0开始计数的)

思路:

把S作为根节点连接其他A,会发现,只有当这个树是一个最小生成树的时候,总距离是最小的;可以用BFS求出点每个A到其他点的点A或者S的距离,然后用prim求出最小生成树的值;

坑点:输入的时候用get()吃掉空格 和回车,以前都是习惯性用getchar()吃回车的,不知道为什么不行,下次就统一用gets吧;

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>

using namespace std;

const int Maxn = 55;
const int INF = 0x3f3f3f3f;

struct Node {
    int x,y,step;
};

int G[Maxn*Maxn][Maxn*Maxn],used[Maxn][Maxn],vis[Maxn*Maxn],cost[Maxn*Maxn],node,Bvis[Maxn][Maxn];
int dist[5][2]= {{-1,0},{0,1},{1,0},{0,-1}},n,m; // 上右下左
char mp[Maxn][Maxn];

void prim () {
    for (int i = 1; i <= node; ++i) {
        vis[i] = 0;
        cost[i] = INF;
    }
    int ans = 0; cost[1] = 0;

    while (1) {
        int v = -1;
        for (int u = 1; u <= node; ++u) {
            if(!vis[u] && (v == -1 || cost[u] < cost[v])) v = u;
        }
        if(v == -1) break;
        vis[v] = 1; ans+=cost[v];
        for (int u = 1; u <= node; ++u) {
            if(!vis[u] && G[u][v] != INF) {
                cost[u] = min (cost[u],G[u][v]);
            }
        }
    }
    printf("%d\n",ans);
}

void bfs (int xx, int yy, int sNode) {
    memset(Bvis,0,sizeof(Bvis));
    queue<struct Node> qu;
    Node p,tmp,start; start.x = xx; start.y = yy; start.step = 0;
    qu.push(start); Bvis[xx][yy] = 1;

    while (!qu.empty()) {
            p = qu.front(); qu.pop();

            for (int i = 0; i < 4; ++i) {
                tmp.x = p.x + dist[i][0]; tmp.y = p.y + dist[i][1];
                tmp.step = p.step + 1;
                if(tmp.x > 0 && tmp.x <= m && tmp.y >= 0 && tmp.y < n &&
                   !Bvis[tmp.x][tmp.y] && mp[tmp.x][tmp.y] != '#') {
                        if(mp[tmp.x][tmp.y] == 'A' || mp[tmp.x][tmp.y] == 'S') {
                            if(!used[tmp.x][tmp.y]) used[tmp.x][tmp.y] = ++node;
                            int sN = used[tmp.x][tmp.y];
                            G[sN][sNode] = tmp.step;
                            G[sNode][sN] = tmp.step;
                        }
                        Bvis[tmp.x][tmp.y] = 1;
                        qu.push(tmp);
                }
            }
    }
}

void init () {
    node = 0;
    for (int i = 1; i <= Maxn*Maxn; ++i) {
        for (int j = 1; j <= Maxn*Maxn; ++j) {
            if(i == j) G[i][j] = 0;
            else G[i][j] = INF;
        }
    }
    memset(used,0,sizeof(used));
    memset(mp,0,sizeof(mp));
}

int main(void)
{
    int t;
    char tmp[200];
    scanf("%d",&t);
    while (t--) {
        scanf("%d%d",&n,&m);
        gets(tmp);
        init ();
        for (int i = 1; i <= m; ++i) {
            gets(mp[i]);
        }

        for (int i = 1; i <= m; ++i) {
            for (int j = 0; j < n; ++j) {
                if(mp[i][j] == 'A') {
                    if(!used[i][j]) used[i][j] = ++node;
                    bfs (i,j,used[i][j]);
                }
            }
        }
        prim ();
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/godleaf/article/details/81450926
今日推荐