涉及点:bfs 离散化 最小生成树
把S和A同等处理,为每个S,A编号,bfs计算所有点对之间的距离,构成边集;
用最小生成树算法连接点,结果就是所求。
恶心的是这题的数据,用getchar()或%*c读不掉数字后面的回车,会WA,得用gets()或\n读掉。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<climits>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#include<list>
#define LL long long
#define maxn 1100
using namespace std;
char _map[60][60];
bool vis[60][60];
bool use[60][60];
struct node
{
int u,v,w;
friend bool operator<(node a,node b)
{
return a.w<b.w;
}
}rd[maxn*maxn];
int num[maxn*maxn];
int top;
int mr[]={0,0,1,-1};
int mc[]={1,-1,0,0};
int father[maxn*maxn];
int _find(int x)
{
int t=x;
while(x!=father[x])
x=father[x];
while(t!=father[t])
{
int temp=t;
t=father[t];
father[temp]=x;
}
return x;
}
bool join(int x,int y)
{
x=_find(x);
y=_find(y);
if(x!=y)
{
father[x]=y;
return true;
}
return false;
}
int getid(int r,int c,int cmax)
{
c+=1;
return c+r*cmax;
}
struct Node
{
int r,c,step;
};
void bfs(int sr,int sc,int R,int C)
{
Node now;
now.r=sr;
now.c=sc;
now.step=0;
memset(vis,false,sizeof(vis));
queue<Node>que;
que.push(now);
vis[sr][sc]=true;
use[sr][sc]=true;
int u=getid(sr,sc,C);
while(!que.empty())
{
Node temp=que.front();
que.pop();
if((_map[temp.r][temp.c]=='A' ||_map[temp.r][temp.c]=='S' ) && temp.step!=0)
{
rd[top].u=u;
rd[top].v=getid(temp.r,temp.c,C);
rd[top++].w=temp.step;
}
for(int i=0;i<4;++i)
{
int nr=temp.r+mr[i];
int nc=temp.c+mc[i];
if(nr>=0 && nc>=0 && nr<R && nc<C && !vis[nr][nc] &&_map[nr][nc]!='#' && !use[nr][nc])
{
now.r=nr;
now.c=nc;
now.step=temp.step+1;
vis[nr][nc]=true;
que.push(now);
}
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
top=0;
memset(use,false,sizeof(use));
int r,c;
scanf("%d%d",&c,&r);
char tt[100];
cin.getline(tt,10000,'\n');
for(int i=0;i<r;++i)
{
cin.getline(_map[i],110000);
}
for(int i=0;i<r;++i)
{
for(int j=0,len=strlen(_map[i]);j<len;++j)
{
if(_map[i][j]=='A' || _map[i][j]=='S')
{
bfs(i,j,r,c);
}
}
}
int t=0;
for(int i=0;i<top;++i)
{
num[t++]=rd[i].u;
num[t++]=rd[i].v;
}
sort(num,num+t);
t=unique(num,num+t)-num;
for(int i=0;i<top;++i)
{
rd[i].u=lower_bound(num,num+t,rd[i].u)-num+1;
rd[i].v=lower_bound(num,num+t,rd[i].v)-num+1;
}
for(int i=0;i<=t;++i)
{
father[i]=i;
}
sort(rd,rd+top);
LL ans=0;
// cout<<"top=="<<top<<endl;
for(int i=0;i<top;++i)
{
// cout<<rd[i].u<<" "<<rd[i].v<<" "<<rd[i].w<<endl;
if(join(rd[i].u,rd[i].v))
{
ans+=rd[i].w;
}
}
printf("%lld\n",ans);
}
}