最小生成树问题
先用搜索求出g[i][j]求目标i到目标j的距离
然后prim算法轻松搞定
注意输入后面会多出空格
#include<cstdio>
#include<cstring>
using namespace std;
#define M 105
#define MAX 900000000
int g[M][M];
int d[M];
char s[M][M];
bool vis[M][M];
bool bvis[M];
int p[M][M];
int n,m,total,ans;
struct Node
{
int x,y;
int step;
}a[M],F[M*M];
int nx[]={1,0,0,-1};
int ny[]={0,1,-1,0};
void read()
{
int i,j;
total=0;
for(i=0;i<n;i++)
{
gets(s[i]);
for(j=0;j<m;j++)
{
if(s[i][j]=='A'||s[i][j]=='S')
{
p[i][j]=total;
a[total].x=i;
a[total++].y=j;
}
}
}
}
void find(int x,int y)
{
memset(vis,0,sizeof(vis));
vis[x][y]=true;
int pre=0,rea=1;
F[pre].x=x;
F[pre].y=y;
F[pre].step=0;
int i,tx,ty;
while(pre<rea)
{
for(i=0;i<4;i++)
{
tx=F[pre].x+nx[i];
ty=F[pre].y+ny[i];
if(!vis[tx][ty]&&s[tx][ty]!='#')
{
F[rea].x=tx;
F[rea].y=ty;
F[rea].step=F[pre].step+1;
if(s[tx][ty]=='A'||s[tx][ty]=='S')
{
g[ p[x][y] ][ p[tx][ty] ]=F[rea].step;
}
rea++;
vis[tx][ty]=true;
}
}
pre++;
}
}
void init()
{
int i;
memset(g,0,sizeof(g));
for(i=0;i<total;i++)
{
find(a[i].x,a[i].y);
}
}
void prim()
{
init();
int i,f=1;
int now=0;
ans=0;
for(i=1;i<total;i++)
{
bvis[i]=false;
d[i]=MAX;
}
while(f<total)
{
int t,min=MAX;
for(i=1;i<total;i++)
{
if(!bvis[i]&&d[i]>g[now][i])
{
d[i]=g[now][i];
}
if(!bvis[i]&&d[i]<min)
{
min=d[i];
t=i;
}
}
now=t;
bvis[now]=true;
f++;
ans+=min;
}
}
void answer()
{
printf("%d\n",ans);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&m,&n);
gets(s[1]); //多出空格用gets
read();
prim();
answer();
}
return 0;
}