/*****
真他娘的恶心,超时了一上午,先是编译器有点问题,然后就一直超时,
原来用了两层for循环,最后优化了一下
改成了一层for()循环AC
**/
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
char map[55][55];
int dis[55][55];
int father[10010];
int dx[] = {-1,1,0,0};
int dy[] = {0,0,1,-1};
int vis[55][55] ;
int mss;
struct Node
{
int x,y,step;
}a[10000],b[10000],c[10000];
int n,m;
bool cmp(Node a,Node b)
{
return a.step<b.step;
}
bool solve(int x,int y) //判断边界
{
if(x>=m||x<0||y>=n||y<0)return false;
if(vis[x][y]||map[x][y]=='#')return false;
return true;
}
int find(int x)
{
if(x == father[x])
return x;
return father[x] = find(father[x]);
}
int cur1 ,cur2;
void bfs(int i)
{
memset(dis,0,sizeof(dis));
memset(vis,0,sizeof(vis));
int x = a[i].x,y = a[i].y;
vis[x][y] = 1;
queue <Node> q;
Node N;
N.x = x;N.y = y,N.step = 0;
q.push(N);
while(!q.empty())
{
N = q.front();
q.pop();
for(int i=0;i<4;i++)
{
int nx = N.x+dx[i];
int ny = N.y+dy[i];
if(solve(nx,ny))
{
if(map[nx][ny] == 'A'||map[nx][ny]=='S'){
dis[nx][ny] = N.step+1;
}
vis[nx][ny] = 1;
Node M;
M.x = nx;
M.y = ny;
M.step = N.step+1;
q.push(M);
}
}
}
}
int main()
{
int icase;
char s[10000];
scanf("%d",&icase);
while(icase--)
{
cur1 = 0,cur2 = 0;
scanf("%d%d",&n,&m);gets(s); //
int cur = 0;
for(int i = 0;i < m;i++)
{
gets(map[i]);
for(int j = 0;j < n;j++)
{
if (map[i][j] == 'A'||map[i][j] == 'S')
{
a[cur].x = i;
a[cur++].y = j;
}
}
}
for(int i=0;i<=cur;i++)
father[i] = i;
for(int i=0;i<cur;i++)
{
bfs(i); //在这里优化,一次广搜访问所有的点
for(int j=i+1;j<cur;j++)
{
b[cur1].x = i;
b[cur1].y = j;;
b[cur1++].step = dis[a[j].x][a[j].y];
}
}
int sum = 0;
sort(b,b+cur1,cmp);
for(int i=0;i<cur1;i++)
{
int x = find(b[i].x);
int y = find(b[i].y);
if(x!=y)
{
sum += b[i].step;
father[x] = y;
}
}
printf("%d\n",sum);
}
}
poj 3028 bfs()+克里斯卡尔
最新推荐文章于 2020-08-14 12:12:13 发布