POJ-3026 Borg Maze

来源:互联网 发布:微办公软件 编辑:程序博客网 时间:2024/06/06 05:44
Borg Maze
Time Limit: 1000MS Memory Limit: 65536K

Description

The Borg is an immensely powerful race of enhanced humanoids from the delta quadrant of the galaxy. The Borg collective is the term used to describe the group consciousness of the Borg civilization. Each Borg individual is linked to the collective by a sophisticated subspace network that insures each member is given constant supervision and guidance.

Your task is to help the Borg (yes, really) by developing a program which helps the Borg to estimate the minimal cost of scanning a maze for the assimilation of aliens hiding in the maze, by moving in north, west, east, and south steps. The tricky thing is that the beginning of the search is conducted by a large group of over 100 individuals. Whenever an alien is assimilated, or at the beginning of the search, the group may split in two or more groups (but their consciousness is still collective.). The cost of searching a maze is definied as the total distance covered by all the groups involved in the search together. That is, if the original group walks five steps, then splits into two groups each walking three steps, the total distance is 11=5+3+3.

Input

On the first line of input there is one integer, N <= 50, giving the number of test cases in the input. Each test case starts with a line containg two integers x, y such that 1 <= x,y <= 50. After this, y lines follow, each which x characters. For each character, a space `` '' stands for an open space, a hash mark ``#'' stands for an obstructing wall, the capital letter ``A'' stand for an alien, and the capital letter ``S'' stands for the start of the search. The perimeter of the maze is always closed, i.e., there is no way to get out from the coordinate of the ``S''. At most 100 aliens are present in the maze, and everyone is reachable.

Output

For every test case, output one line containing the minimal cost of a succesful search of the maze leaving no aliens alive.

Sample Input

26 5##### #A#A### # A##S  ####### 7 7#####  #AAA####    A## S ####     ##AAA########  

————————————————————集训9.8的分割线————————————————————

前言:出题人脑子有病,证明如下——

1. 先输入的是列,后输入的是行。

2. 地图当中有很多空格,%s的跪了。

3. 输入完列和行之后,会有很多干扰性的空格!getchar()的挂了。

Prim只是一个模板,但是建图不容易。

从S开始,分化之后找到一个A,然后再分化。每次分化都是为了走最近的路,不要回头。正好和Prim的过程一样。但是距离要受迷宫的限制。因此需要把每个可以作为Borg的点当作起点各自BFS一遍。这样就可以得到每两个点之间的权值。然后套上Prim就行了。

图不但要记录字符,如果是Borg的话还要记录id,以便保存每条边的长。

代码如下:

/*ID: j.sure.1PROG:LANG: C++*//****************************************/#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <cmath>#include <stack>#include <queue>#include <vector>#include <map>#include <string>#include <iostream>#define INF 2e9using namespace std;/****************************************/#define LIM nt.x >= 0 && nt.x < n && nt.y >= 0 && nt.y < mconst int N = 105, d[][2] = {-1, 0, 0, 1, 1, 0, 0, -1};struct Node {int x, y, step;} st[N];struct MAP {int id; char c;} mat[N][N];int dis[N][N], low[N];int n, m, cnt;bool vis[N][N];queue <Node> q;void bfs(Node &start, int sid){while(!q.empty()) q.pop();memset(vis, 0, sizeof(vis));vis[start.x][start.y] = true;q.push(start);Node t, nt;while(!q.empty()) {t = q.front(); q.pop();for(int dd = 0; dd < 4; dd++) {int &nx = nt.x = t.x + d[dd][0];int &ny = nt.y = t.y + d[dd][1];nt.step = t.step + 1;if(LIM && !vis[nx][ny] && mat[nx][ny].c != '#') {if(mat[nx][ny].c == 'A') {dis[sid][mat[nx][ny].id] = nt.step;}vis[nx][ny] = true;q.push(nt);//一开始这句居然忘了写!}}}}int prim(){for(int i = 0; i < cnt; i++) {low[i] = dis[0][i];}low[0] = -1;int sum = 0, k;for(int i = 1; i < cnt; i++) {int mini = INF;for(int j = 0; j < cnt; j++) if(low[j] != -1) {if(mini > low[j]) {mini = low[j];k = j;}}sum += mini;low[k] = -1;for(int j = 0; j < cnt; j++) if(low[j] != -1) {low[j] = min(low[j], dis[k][j]);}}return sum;}int main(){#ifdef J_Surefreopen("3026.in", "r", stdin);//freopen(".out", "w", stdout);#endifint T;scanf("%d", &T);while(getchar() != '\n');while(T--) {scanf("%d%d", &m, &n);while(getchar() != '\n');char str[N];cnt = 0;memset(dis, 0, sizeof(dis));for(int i = 0; i < n; i++) {gets(str);//只有gets()能hold住了吧for(int j = 0; j < m; j++) {mat[i][j].c = str[j];if(str[j] == 'S' || str[j] == 'A') {mat[i][j].c = 'A';mat[i][j].id = cnt;st[cnt].x = i; st[cnt].y = j; st[cnt++].step = 0;}}}for(int i = 0; i < cnt; i++) {bfs(st[i], i);}printf("%d\n", prim());}return 0;}


0 0
原创粉丝点击