您的位置:首页 > 其它

POJ 3026 Borg Maze 最小生成树

2015-10-03 23:59 302 查看
这道题大意很好懂,有一个S点和不超过100个A点,求这些点构成的完全图的最小生成树。

题意虽简单,但实现略繁琐,而且Input有陷阱。

在n,m这一行行末会有多余空格。。。(无聊。)

然后用了prim来做(代码有点乱)。

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;

const int maxn = 110;
const int maxDot = 110;
const int INF = 0x3f3f3f3f;

int g[maxn][maxn];
int n, m, T;
int dis[maxDot][maxDot];
bool vis[maxn][maxn];
int cost[maxDot];
int cnt;

struct nd {
int x, y, dpt;
} dot[maxDot];

struct node {
int x, y, dpt;
node(int a, int b, int c) : x(a), y(b), dpt(c) {}
};

int dx[4] = { -1, 0, 1, 0 };
int dy[4] = { 0, -1, 0, 1 };

bool check(int x, int y) {
return x >= 0 && x < n && y >= 0 && y < m && g[x][y] >= 0;
}

void bfs(int st) {
memset(vis, 0, sizeof(vis));
queue<node> q;
dot[st].dpt = 0;
q.push(node(dot[st].x, dot[st].y, dot[st].dpt));
while (!q.empty()) {
node u = q.front(); q.pop();
int x = u.x, y = u.y;
if (vis[x][y]) continue;
vis[x][y] = 1;
if (g[x][y] >= 1) {
int ed = g[x][y];
dis[st][ed] = dis[ed][st] = u.dpt;
}
for (int i = 0; i < 4; i++)
if (check(x + dx[i], y + dy[i]))
q.push(node(x + dx[i], y + dy[i], u.dpt + 1));
}
}

bool used[maxDot];

int prim() {
for (int i = 1; i <= cnt; i++) {
cost[i] = INF;
used[i] = 0;
}
cost[1] = 0;
int res = 0;
while (true) {
int v = -1;
for (int u = 1; u <= cnt; u++)
if (!used[u] && (v == -1 || cost[v] > cost[u]))
v = u;
if (v == -1) break;
used[v] = 1;
res += cost[v];
for (int u = 1; u <= cnt; u++)
cost[u] = min(cost[u], dis[v][u]);
}
return res;
}

int main() {
char s[maxn];
scanf("%d", &T);
while (T--) {
scanf("%d%d", &m, &n);
while ('\n' != getchar()) ;
memset(g, -1, sizeof(g));
cnt = 1;
for (int i = 0; i < n; i++) {
fgets(s, maxn, stdin);
int len = strlen(s) - 1;
for (int j = 0; j < len; j++)
if (s[j] == '#')
g[i][j] = -1;
else if (s[j] == ' ')
g[i][j] = 0;
else if (s[j] == 'A')
g[i][j] = ++cnt;
else
g[i][j] = 1;
}
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
if (g[i][j] > 0) {
int t = g[i][j];
dot[t].x = i;
dot[t].y = j;
}
for (int i = 1; i <= cnt; i++)
for (int j = 1; j <= cnt; j++)
dis[i][j] = INF;
for (int i = 1; i <= cnt; i++)
bfs(i);
for (int i = 1; i <= cnt; i++) dis[i][i] = 0;
printf("%d\n", prim());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: