zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Winsock 2 入门指南
    Winsock 2 入门指南
    [手游新项目历程]-40-linux环境实现C/C++程序崩溃退出时打印栈信息
    1月下旬解题
    poj1226,poj3080
    poj3666
    poj3067
    poj12月其他题解(未完)
    poj1823,3667
    poj2352
  • 原文地址:https://www.cnblogs.com/gabo/p/2582108.html
Copyright © 2011-2022 走看看