DestinHistoire

 

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编辑  收藏  举报

导航