poj3026 bfs + Prim

对每一个人'用一次BFS,记录其他人与他的距离,并建图。

图建好后,用Prim求最小生成树即为答案。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

#define M 105
#define VN 2500
#define INF 1000000000

int map[M][M], dist[M][M], que_x[VN], que_y[VN], g[M][M];
int r, c, dir[4][2] = { {-1, 0}, {0, -1}, {1, 0}, {0, 1} };
bool visit[M / 2][M / 2];

void BFS(int x, int y)
{
    memset(visit, false, sizeof(visit));
    memset(dist, 0, sizeof(dist));

    int head, tail, tmp_x, tmp_y, i, j;

    visit[x][y] = true; dist[x][y] = 0;
    head = 0; tail = 1;
    que_x[0] = x; que_y[0] = y;
    while (head < tail)
    {
        tmp_x = que_x[head]; tmp_y = que_y[head]; head++;
        for (i = 0; i < 4; i++)
        {
            int tx = tmp_x + dir[i][0];
            int ty = tmp_y + dir[i][1];
            if (tx > 0 && tx < r && ty > 0 && ty < c && !visit[tx][ty] && map[tx][ty] >= 0)
            {
                 dist[tx][ty] = dist[tmp_x][tmp_y] + 1;
                 visit[tx][ty] = true;
                 que_x[tail] = tx; que_y[tail] = ty; tail++;
                 if (map[tx][ty] > 0)
                 {
                     g[map[x][y]][map[tx][ty]] = dist[tx][ty];
                     g[map[tx][ty]][map[x][y]] = dist[tx][ty];
                 }
            }
        }
    }
}

int Prim(int start, int num)
{
    bool vis[VN];
    int d[VN], i, j, tmp, cur, ans = 0;

    memset(vis, false, sizeof(vis));
    for (i = 2; i <= num; i++) d[i] = INF;
    d[1] = 0;
    for (i = 1; i <= num; i++)
    {
        tmp = INF;
        cur = -1;
        for (j = 1; j <= num; j++)
        {
            if (!vis[j] && d[j] < tmp)
            {
                tmp = d[j];
                cur = j;
            }
        }

        if (cur == -1) break;
        ans += tmp;
        vis[cur] = true;
        for (j = 1; j <= num; j++)
            if (!vis[j] && g[cur][j] < d[j])
                d[j] = g[cur][j];
    }
    return ans;
}

int main()
{
    int n, i, j, num;
    char tmp[M / 2];

    cin >> n;
    while (n--)
    {
        memset(g, 0, sizeof(g));
        cin >> r >> c;
        num = 1;
        gets(tmp);  //在输入的r,c的后面还有空格,gets掉,题目的变态的地方,discuss里面有。
        for (i = 0; i < c; i++)
        {
            gets(tmp);
            for (j = 0; j < r; j++)
            {
                if (tmp[j] == '#') map[i][j] = -1;
                else if (tmp[j] == ' ') map[i][j] = 0;
                else if (tmp[j] == 'A') map[i][j] = ++num;
                else if (tmp[j] == 'S') map[i][j] = 1;
            }
        }
        for (i = 0; i < c; i++)
            for (j = 0; j < r; j++)
                 if (map[i][j] > 0)
                     BFS(i, j);
        cout << Prim(1, num) << endl;
    }
    return 0;
}


你可能感兴趣的:(c)