bfs Figure & build the minimum spanning tree - Borg Maze POJ - 3026

Borg Maze POJH - 3026

Ideas:

Starting from s (seen as a lot of people) meaning can go from multiple directions, to find the shortest path to A's. As a find A, then starting from the current position at this time and the number of steps is 0, and went to look for other A.

Here Insert Picture Description
Can also direct violence to solve each letter of the path to the other letters were built map, set off from each letter, multiple BFS can be solved.

code :

#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;
}

Published 92 original articles · won praise 7 · views 3730

Guess you like

Origin blog.csdn.net/dajiangyou123456/article/details/104398233
Recommended