BFS図&最小スパニングツリーを構築 - ボルグ迷路POJ - 3026

ボルグ迷路POJH - 3026

アイデア:

sから始まるAさんへの最短経路を見つけるために、複数の方向から行くことができることを意味し(たくさんの人として見られます)。検索のAとしては、この時点での現在位置から開始し、ステップ数は0であり、他のA.を探しに行きました

ここに画像を挿入説明
また、直接的な暴力は、各文字からオフに設定されたマップを構築した他の文字、パスの各文字を解決することができ、複数のBFSを解決することができます。

コード:

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 55, M = N * N;
int n, m, t, sx, sy, cnt, mcnt, path[N][N], id[N][N], p[N]; //代表某个字母到达(i, j)的距离 
char g[N][N];
int dx[4] = {1, 0, 0, -1};
int dy[4] = {0, 1, -1, 0};
struct Node {
	int x, y, sx, sy, d;
	Node(int x, int y, int sx, int sy, int d): x(x), y(y), sx(sx), sy(sy), d(d){}
	bool operator < (const 	Node&o) const {
		return d > o.d;
	}	 
}; 
struct E {
	int u, v, w;
	bool operator < (const E&o) const {
		return w < o.w;
	}
} e[M];  
int find(int x){return x == p[x] ? x : (p[x] = find(p[x]));}
void bfs() {
	priority_queue<Node> q;
	path[sx][sy] = 0;
	id[sx][sy] = ++cnt; //给每个字母标号 
	q.push(Node(sx, sy, sx, sy, 0));
	while (!q.empty()) {
		Node t = q.top();
		q.pop();
		for (int i = 0; i < 4; i++) {
			int fx = t.x + dx[i];
			int fy = t.y + dy[i];
			if (fx >= 0 && fy >= 0 && fx < n && fy < m && g[fx][fy] != '#') {
				if (t.d + 1 < path[fx][fy]) {
					if (t.sx == fx && t.sy == fy) continue;//避免自己与自己连边 
					path[fx][fy] = t.d + 1;
					if (g[fx][fy] == 'A') {
						q.push(Node(fx, fy, fx, fy, 0));
						if (!id[fx][fy]) id[fx][fy] = ++cnt;
						//添加边
						e[++mcnt].u = id[t.sx][t.sy]; 
						e[mcnt].v = id[fx][fy];
						e[mcnt].w = t.d + 1;
					} else {
						q.push(Node(fx, fy, t.sx, t.sy, path[fx][fy]));
					}
				}
			} 
		}
	}
} 
int main() {
	scanf("%d", &t);
	while (t--) {
		memset(path, 0x3f, sizeof(path)); cnt = mcnt = 0;
		memset(id, 0, sizeof(id));
		scanf("%d%d", &m, &n);
		gets(g[0]); //消除上面的换行 
		for (int i = 0; i < n; i++) gets(g[i]);
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				if (g[i][j] == 'S') sx = i, sy = j;
			}
		}
		bfs(); //确定字母之间的关系 
		int ans = 0;
		sort(e + 1, e + 1 + mcnt); 
		for (int i = 1; i <= cnt; i++) p[i] = i; //初始化并查集 
		for (int i = 1; i <= mcnt; i++) {
			int fu = find(e[i].u), fv = find(e[i].v);
			if (fu != fv) {
				ans += e[i].w;
				p[fu] = fv;
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}

公開された92元の記事 ウォン称賛7 ビュー3730

おすすめ

転載: blog.csdn.net/dajiangyou123456/article/details/104398233