挺综合的一题,就是空格有些无语,多亏discuss前辈们的指点。
渣代码抛砖引玉。
#include <iostream>
#include <queue>
using namespace std;
#define maxn 1010
#define maxm 100010
#define INF 100000000
int cas,n,m;
char s[110][110];
struct edge {
int x,y,d,next;
}g[maxm];
struct data {
int x,y;
}p[110];
queue<data> q;
int tot,first[maxn],pre[maxn],ans,sum,v[110][110],tx,ty;
int dx[4] = {1,0,-1,0};
int dy[4] = {0,1,0,-1};
void add(int x,int y,int d) {
tot++;
g[tot].x=x;
g[tot].y=y;
g[tot].d=d;
g[tot].next=first[x];
first[x]=tot;
tot++;
g[tot].x=y;
g[tot].y=x;
g[tot].d=d;
g[tot].next=first[y];
first[y]=tot;
}
void prim() {
int t,i,j,k,min,lowcost[maxn];
for (i=1;i<=n;i++) lowcost[i]=INF;
memset(pre,0,sizeof(pre));
for (t=first[1];t!=-1;t=g[t].next)
lowcost[g[t].y]=g[t].d;
for (i=2;i<=n;i++)
pre[i]=1;
lowcost[1]=0;
for (i=2;i<=n;i++) {
min=INF;
for (j=2;j<=n;j++)
if (lowcost[j]<min && lowcost[j]!=0) {
min=lowcost[j];
k=j;
}
ans+=min;
lowcost[k]=0;
for (t=first[k];t!=-1;t=g[t].next)
if (g[t].d<lowcost[g[t].y]) {
lowcost[g[t].y]=g[t].d;
pre[g[t].y]=k;
}
}
}
void bfs(int i) {
while (!q.empty()) q.pop();
data tmp = p[i];
q.push(tmp);
v[tmp.x][tmp.y] = 0;
while (!q.empty()) {
tmp = q.front();
q.pop();
for (int k=0;k<4;k++) {
tx = tmp.x+dx[k];
ty = tmp.y+dy[k];
if (tx>=1 && tx<=n && ty>=0 && ty<m && v[tx][ty]==-1 && s[tx][ty]!='#') {
v[tx][ty] = v[tmp.x][tmp.y]+1;
data t;
t.x = tx;
t.y = ty;
q.push(t);
}
}
}
}
int main() {
scanf("%d",&cas);
while (cas--) {
scanf("%d%d",&m,&n);
gets(s[0]);
for (int i=1;i<=n;i++)
gets(s[i]);
sum = 0;
for (int i=1;i<=n;i++)
for (int j=0;j<m;j++)
if (s[i][j]=='A'||s[i][j]=='S') {
sum++;
p[sum].x = i;
p[sum].y = j;
}
tot = 0;
memset(first,-1,sizeof(first));
for (int i=1;i<sum;i++) {
memset(v,-1,sizeof(v));
bfs(i);
for (int j=i+1;j<=sum;j++)
add(i,j,v[p[j].x][p[j].y]);
}
ans = 0;
n = sum;
prim();
printf("%d\n",ans);
}
return 0;
}