POJ3026 - Borg Maze

此题可以分为拆分为两个问题:

1、求起止点S和n个外星人A,共n+1个顶点的两两距离

2、求这n+1个顶点的最小生成树


//Memory Time
//220K	16MS
  
#include<iostream>  
#include<stdio.h>
#include<queue>
using namespace std;  

#define MAXCONST 2000000000;
char s[100][100];
struct mapInfo
{
	int deep;
	char map;
	bool isSearched;
};
mapInfo map[100][100];

bool alienAdded[200];
int  alienDis[200];
struct alienPos
{
	char row;
	char col;
};
alienPos aliPos[200];
alienPos dir[4] = {{1,0},{-1,0},{0,1},{0,-1}};
  
void bsf(char s[][100],mapInfo map[][100], int startRow, int startCol,int alienQueue[], int rowNum, int colNum, int alienNum);
  
int main()
{
	int T;
	scanf("%d",&T);
	while(T > 0)
	{
		T--;
		
		int col, row;
		scanf("%d", &col);
		scanf("%d", &row);
		gets(s[0]);
		for(int i = 0; i < row; i++)
		{
			gets(s[i]);	
		}
		int startRow, startCol, alienNum = 0;
		for(int i = 0; i < row; i++)
			for(int j = 0; j < col; j++)
			{
				if(s[i][j] == 'A' )
				{
					map[i][j].map = alienNum;
					aliPos[alienNum].row = i;
					aliPos[alienNum].col = j; 
					alienNum++;
				}
				else if(s[i][j] == 'S')
				{
					startRow = i;
					startCol = j;
				}
			}
		
		for(int i = 0; i < alienNum; i++)
		{
			alienDis[i] = MAXCONST;
			alienAdded[i] = 0;
		}
		
		int total = 0;
		for(int i = alienNum; i > 0;i--)
		{
			bsf(s, map, startRow, startCol, alienDis, row, col, alienNum);

			int tempMin = MAXCONST;
			for(int j = 0; j < alienNum; j++)
			{
				if(alienDis[j] < tempMin && alienAdded[j] == 0)
				{
					tempMin = alienDis[j];
					startRow = aliPos[j].row;
					startCol = aliPos[j].col;
				}
			}
			alienAdded[map[startRow][startCol].map] = 1; 
			total += tempMin;
		}
		
		printf("%d\n",total);
	}
	return 0;
}

void bsf(char s[][100], mapInfo map[][100], int startRow, int startCol,int alienQueue[], int rowNum, int colNum, int alienNum)
{
	for(int i = 0; i < rowNum; i++)
	{
		for(int j = 0; j < colNum; j++)
		{
			map[i][j].deep = 0;
			map[i][j].isSearched  = 0;
		}
	}
	queue<alienPos> que;
	alienPos temp;
	temp.row = startRow;
	temp.col = startCol;
	que.push(temp);
	while(!que.empty())
	{
		alienPos tempP = que.front();
		que.pop();
		map[tempP.row][tempP.col].isSearched = 1;
		for(int i = 0 ; i < 4; i++)
		{
				int tempi = tempP.row + dir[i].row;
				int tempj = tempP.col + dir[i].col;
				if(map[tempi][tempj].isSearched == 0)
				{
					map[tempi][tempj].deep = map[tempP.row][tempP.col].deep + 1;
					map[tempi][tempj].isSearched = 1;
					if(s[tempi][tempj] == ' ')
					{
						alienPos temp;
						temp.row = tempi;
						temp.col = tempj;
						que.push(temp);
					}
					else if(s[tempi][tempj] == 'A')
					{
						alienNum--;
						int tempPT = map[tempi][tempj].map;
						if(map[tempi][tempj].deep < alienQueue[tempPT])
							alienQueue[tempPT] = map[tempi][tempj].deep;
							
						if(alienNum == 0)
							break;
					}
				}
		}
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值