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;

}

 

你可能感兴趣的:(poj)