poj 3026 Borg Maze

poj 3026 Borg Maze
//poj 3026 Borg Maze
//bfs+MST(广搜+最小生成树)
//这题的英文实在看不懂,百度了别人的解题报告才知道意思的,所以要多多使用英语来慢慢提高才行
//这题的意思是要通过'S'去找'A',找到一个'A'就把它同化掉帮忙去同化别的'A'
//其实就是最小生成树问题,只要用广搜求出每个点之间的距离后用prim就可以了


#include <stdio.h>
#include <string.h>
#include <queue>

#define N 55
#define INF 1<<30
using namespace std;

struct NODE
{
    int x, y, step; //step record step when bfs(记录步数)
}node[105]; //at most 100 aliens,in addition to start of the search(至少100个'A'再加一个'S')

int line, row, cnt, ans;
char map[N][N];
int mark[N][N], dis[105][105], dirx[4] = {0, 1, 0, -1}, diry[4] = {-1, 0, 1, 0};
//mark show the identifier of 'A' or 'S'(mark标记'A'和'S'的编号)
//dis recode the distance between two node(dis标记两个结点间的距离)
int dist[N];    //recorde the shortest distance when process prim(dist是在prim内记录最短距离的)
bool vis[N][N], vist[N];
//vis is used in bfs, vist is used in prim(vis是bfs时用来标记是否遍历,vist是prim内结点是否遍历)


void bfs(int index)
{
    queue<NODE> que;
    memset(vis, false, sizeof(vis));
    NODE now, next;
    node[index].step = 0;
    que.push(node[index]);
    vis[node[index].x][node[index].y] = true;
    while(!que.empty())
    {
        now = que.front();
        que.pop();
        int x = now.x, y = now.y;
        for(int i = 0; i < 4; ++i)
        {
            int tx = x + dirx[i], ty = y +diry[i];
            if(vis[tx][ty] == false && map[tx][ty] != '#')
            {
                next.x = x + dirx[i];
                next.y = y + diry[i];
                vis[next.x][next.y] = true;
                next.step = now.step + 1;
                que.push(next);
                if(map[next.x][next.y] == 'A' || map[next.x][next.y] == 'S')
                    dis[ mark[ node[index].x ][ node[index].y ] ][ mark[next.x][next.y] ] = next.step;
            }

        }
    }
}


int prim()
{
    for(int i = 0; i < cnt; ++i)
    {
        dist[i] = INF;
        vist[i] = false;
    }
    dist[0] = 0;
    while(1)
    {
        int min = INF, now = -1;
        for(int i = 0; i < cnt; ++i)
        {
            if(min > dist[i] && vist[i] == false)
            {
                min = dist[i];
                now = i;
            }
        }
        if(now == -1)
            return ans;
        ans += min;
        vist[now] = true;
        for(int i = 0; i < cnt; ++i)
            if(vist[i] == false && dist[i] > dis[now][i])
                dist[i] = dis[now][i];
    }
    return ans;
}

int main()
{
    int n_case;
    scanf("%d", &n_case);
    while(n_case--)
    {
        cnt = ans = 0;
        memset(mark, 0, sizeof(mark));
        scanf("%d%d", &row, &line);
        char ch;
        while(ch = getchar(), ch != '\n');
        for(int i = 0; i < line; ++i)
        {
            for(int j = 0; j < row; ++j)
            {
                map[i][j] = getchar();
                if(map[i][j] == 'A' || map[i][j] == 'S')
                {
                    mark[i][j] = cnt;
                    node[cnt].x = i;
                    node[cnt++].y = j;
                }
            }
            while(ch = getchar(), ch != '\n');
        }
        for(int i = 0; i < cnt; ++i)
            bfs(i);  //get shortest distance between any pair of charater besides '#'
        prim();
        printf("%d\n", ans);
    }
    return 0;
}

 

posted @ 2012-07-09 08:30  gabo  阅读(178)  评论(0编辑  收藏  举报