我好像是理解错题意了。。。现在我想的是当人们找到达到一个目的点后才可以分成多批人。
看了网上的一些代码,但貌似都没有解决一种情况,测试数据貌似也没有这种情况。。。
空空A空空 在第一行时用gets,调试时发现这一行的A在第一个位置,这一行的长度为3,也就是A前面的两个空没有被储存在数组中。
先这样吧。
用bfs求出任意两点的距离,之后裸的prim
#include<iostream>
#include<cstring>
#include<math.h>
#include<algorithm>
#include<queue>
#include<stdio.h>
using namespace std;
#define mem(arr,a) memset(arr,a,sizeof(arr))
#define V 1000+4
#define sc(t) scanf("%d",&t);
#define pow(a) ((a)*(a))
int cost[V][V];
char maps[V][V];
int vis[V];
int used[V][V];
int minCost[V];
int marks[V][V];
int t;
int col, row;
int n, m;
struct node{
int x, y;
int steps;
};
node vet[V];
bool judge(node v){
if (v.x > 0 && v.y > 0 && v.x <= n&&v.y <= n&&maps[v.x][v.y]!='#'&&!used[v.x][v.y])return true;
return false;
}
void bfs(int s){
queue<node>q;
node t = vet[s];
mem(used, 0);
used[t.x][t.y] = 1;
int dx[] = { 1, 0, -1, 0 };
int dy[] = { 0, 1, 0, -1 };
q.push(t);
while (!q.empty()){
node u = q.front(); q.pop();
for (int i = 0; i < 4; i++){
node v = u;
v.x += dx[i];
v.y += dy[i];
v.steps++;
if (judge(v)){
used[v.x][v.y] = 1;
if (maps[v.x][v.y] == 'A' || maps[v.x][v.y] == 'S'){
for (int j = 0; j < n; j++){
if (vet[j].x == v.x&&vet[j].y == v.y){
cost[s][j] = cost[j][s] = v.steps;
}
}
}
q.push(v);
}
}
}
}
void prim(){
int sum = 0;
for (int i = 0; i < n; i++){
minCost[i] = cost[0][i];
vis[i] = 0;
}
while (1){
int v = -1;
for (int i = 0; i < n; i++){
if (!vis[i] && (v == -1 || minCost[i] < minCost[v]))v = i;
}
if (v == -1)break;
vis[v] = 1;
sum += minCost[v];
for (int i = 0; i < n; i++){
minCost[i] = min(minCost[i], cost[v][i]);
}
}
cout << sum << endl;
}
int main(){
sc(t);
while (t--){
n = 0;
scanf("%d%d ", &col, &row);
mem(marks, 0);
for (int j = 1; j <= row; j++)
gets(maps[j]);
for (int i = 1; i <= row; i++){
for (int j = 1; j <= col; j++){
if (maps[i][j] == 'A' || maps[i][j] == 'S'){
vet[n].x = i; vet[n].y = j;
vet[n].steps = 0;
n++;
}
}
}
for (int i = 0; i < n; i++)
bfs(i);
prim();
}
}