BZOJ-1295 [SCOI2009]最长距离(SPFA)
题目描述
\(n\times m(1\leq n,m\leq 30)\) 的矩阵,有的格子含有障碍物。 如果从格子 \(A\) 可以走到格子 \(B\),那么两个格子的距离就为两个格子中心的 欧几里德距离。 如果从格子 \(A\) 不可以走到格子 \(B\),就没有距离。 如果格子 \(X\) 和格子 \(Y\) 有公共边,并且 \(X\) 和 \(Y\) 均不含有障碍物,就可以从 \(X\) 走到 \(Y\)。可以移走 \(t(0\leq t\leq 30)\) 块障碍物,求所有格子间的最大距离。 保证移走 \(t\) 块障碍物以后,至少有一个格子不含有障碍物。
分析
以每个点 \((i,j)\) 为起点跑 \(\text{SPFA}\),如果 \((i,j)\) 到其他点的最短路 \(\leq t\),更新欧几里得距离的最大值,时间复杂度 \(O(n^4)\)。
代码
#include<bits/stdc++.h>
using namespace std;
int n,m,t;
int mp[50][50],dist[50][50];
bool vis[50][50];
int dx[4]={0,1,-1,0};
int dy[4]={1,0,0,-1};
double ans;
double Distance(double x1,double y1,double x2,double y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
void SPFA(int Sx,int Sy)
{
queue<pair<int,int> > Q;
memset(dist,0x3f,sizeof(dist));
memset(vis,0,sizeof(vis));
Q.push(make_pair(Sx,Sy));
dist[Sx][Sy]=mp[Sx][Sy];
vis[Sx][Sy]=1;
while(!Q.empty())
{
int x=Q.front().first;
int y=Q.front().second;
vis[x][y]=0;
Q.pop();
for(int i=0;i<4;i++)
{
int nx=x+dx[i];
int ny=y+dy[i];
if(1<=nx&&nx<=n&&1<=ny&&ny<=m)
{
if(dist[nx][ny]>dist[x][y]+mp[nx][ny])
{
dist[nx][ny]=dist[x][y]+mp[nx][ny];
if(!vis[nx][ny])
{
vis[nx][ny]=1;
Q.push(make_pair(nx,ny));
}
}
}
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(dist[i][j]<=t&&Distance(Sx,Sy,i,j)>ans)
ans=Distance(Sx,Sy,i,j);
}
int main()
{
cin>>n>>m>>t;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%1d",&mp[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
SPFA(i,j);
printf("%.6lf\n",ans);
return 0;
}
posted on 2020-12-03 15:24 DestinHistoire 阅读(39) 评论(0) 编辑 收藏 举报