avatar
fireworks99
keep hungry keep foolish

POJ 3026 Brog Maze(BFS+Prim)

Description

将S和A所在点连成最小生成树

Analyze

用BFS求出(S、A)各点之间的最小距离,建立图的边

求最小生成树

Code

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 55;
const int INF = 0x3f3f3f3f;
typedef pair<int, int> P;

int n, m, node[N][N], num, dis[N][N], e[N * N][N * N], low[N * N];
char str[N], mp[N][N];
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
bool vis[N][N], used[N * N];


void BFS(int x, int y)
{
    memset(vis, 0, sizeof(vis));
    memset(dis, 0, sizeof(dis));

    queue<P> q;
    q.push(P(x, y));
    vis[x][y] = 1;

    while(!q.empty())
    {
        P now = q.front();
        q.pop();

        int nowx = now.first;
        int nowy = now.second;
        if(node[nowx][nowy])
            e[ node[x][y] ][ node[nowx][nowy] ] = dis[nowx][nowy];
        for(int i = 0; i < 4; ++i)
        {
            int xx = nowx + dx[i];
            int yy = nowy + dy[i];
            if(xx >= 0 && xx < m && yy >= 0 && yy < n)
                if(!vis[xx][yy] && mp[xx][yy] != '#')
                {
                    q.push(P(xx, yy));
                    vis[xx][yy] = 1;
                    dis[xx][yy] = dis[nowx][nowy] + 1;
                }
        }
    }
}

void Prim()
{
    int ans = 0, mmin = INF, pos = 1;
    memset(used, 0, sizeof(used));

    ans += 0, used[pos] = 1;
    for(int i = 1; i <= num; ++i)
        low[i] = e[pos][i];

    int cnt = num;
    while(--cnt)
    {
        mmin = INF;
        for(int i = 1; i <= num; ++i)
            if(!used[i] && low[i] < mmin)
                mmin = low[i], pos = i;

        ///if(mmin == INF)

        ans += mmin, used[pos] = 1;
        for(int i = 1; i <= num; ++i)
            if(!used[i] && low[i] > e[pos][i])
                low[i] = e[pos][i];
    }
    cout << ans << '\n';
}

int main()
{
    int _;
    scanf("%d", &_);
    while(_--)
    {
        scanf("%d %d", &n, &m);

        num = 0;
        memset(e, 0, sizeof(e));
        memset(node, 0, sizeof(node));

        gets(str);
        for(int i = 0; i < m; ++i)
            gets(mp[i]);

        for(int i = 0; i < m; ++i)
            for(int j = 0; j < n; ++j)
                if(mp[i][j] == 'A' || mp[i][j] == 'S')
                    node[i][j] = ++num;

        for(int i = 0; i < m; ++i)
            for(int j = 0; j < n; ++j)
                if(node[i][j])
                    BFS(i, j);
        Prim();
    }
    return 0;
}
Site by Baole Zhao | Powered by Hexo | theme PreciousJoy