POJ 3026 Borg Maze
参考博客:https://blog.csdn.net/u014422052/article/details/40210399
一开始拿到题完全看不懂……
好不容易理解了题意发现做不了,想单用bfs的话得每次判断两个方向,实在太复杂就不想下去了
看了大神操作:发现原来这还是最小生成树的拓展
需要把每个点都连起来,但是如果不能分裂(变方向)的话,就得多算很多重复的路线,但是现在可以分裂那么就会减少很多这样的路径,我们只需要算出最小生成树的权值就可以了,但是每个点与点之间的距离还是得用bfs求出来的。
我一开始把所有的A和S都单独的存一个结构体里,然后再n^2构造边加入edge中去,但是这样超时了。大神在每一个bfs里面就同时完成边的加入了,效率更高
另外这题的读入也很恶心。。
/**
* Author1: low-equipped w_udixixi
* Author2: Sher丶lock
* Date :2019-08-15
**/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<queue>
#include<map>
#define ll long long
#define pb push_back
#define rep(x,a,b) for (int x=a;x<=b;x++)
#define repp(x,a,b) for (int x=a;x<b;x++)
#define pi 3.14159265358979323846
#define mem(a,x) memset(a,x,sizeof a)
using namespace std;
const int maxn=2500+7;
const int INF=1e9;
const ll INFF=1e18;
int way[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int s[maxn][maxn];
int flag[maxn][maxn];
int fa[maxn];
struct Edge{
int u,v,w;
}edge[maxn*maxn];
struct node {
int x,y;
int step;
}p[maxn*maxn],sx,n1,n2;
int n,m,tol=0;
void add(int u,int v,int w)
{
edge[tol].u=u;
edge[tol].v=v;
edge[tol].w=w;
tol++;
}
int find(int x)
{
if (fa[x]!=-1)return fa[x]=find(fa[x]);
else return x;
}
bool cmp(Edge a,Edge b){return a.w<b.w;}
int solve(int n)
{
int ans=0;
int cnt=0;
mem(fa,-1);
sort(edge,edge+tol,cmp);
repp(i,0,tol)
{
int t1=find(edge[i].u);
int t2=find(edge[i].v);
if (t1!=t2)
{
ans+=edge[i].w;
cnt++;
fa[t1]=t2;
}
if (cnt==n-1)break;
}
return ans;
}
int bfs(int a,int b)
{
sx.x=a;sx.y=b;sx.step=0;
queue<node >q;while(!q.empty())q.pop();
mem(flag,0);
q.push(sx);
while(!q.empty())
{
node n1=q.front();
q.pop();
repp(i,0,4)
{
n2.x=n1.x+way[i][0];
n2.y=n1.y+way[i][1];
if (n2.x<0||n2.x>=n||n2.y<0||n2.y>=m||s[n2.x][n2.y]==-1||flag[n2.x][n2.y]==1)continue;
n2.step=n1.step+1;
flag[n2.x][n2.y]=1;
if (s[n2.x][n2.y]>=1)
{
add(s[a][b],s[n2.x][n2.y],n2.step);
}
q.push(n2);
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&m,&n);
tol=0;
int z=0,num=1;
char s1[maxn];
char x;
gets(s1);
repp(i,0,n)
{
repp(j,0,m)
{
scanf("%c",&x);
if (x=='A'||x=='S')
{
s[i][j]=num;
num++;
}
else if (x==' ')
s[i][j]=0;
else
s[i][j]=-1;
}
getchar();
}
repp(i,0,n)
repp(j,0,m)
if (s[i][j]>=1)
bfs(i,j);
cout<<solve(tol)<<endl;
}
}