此题可以分为拆分为两个问题:
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;
}
}
}
}
}