BZOJ1295: [SCOI2009]最长距离

【传送门:BZOJ1295


简要题意:

  给出一个n*m的矩阵,有障碍物,(a,b)和(c,d)存在距离当且仅当两个点能互相到达,且距离为欧几里德距离

  可以移走t个障碍物,求出距离最大的两个点的距离


题解:

  n,m这么这么小

  直接O(n2m2),跑最短路,水题


参考代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using namespace std;
bool v[31][31];
int d[31][31];
int n,m;
struct node
{
    int x,y;
}list[1100];
char st[31][31];
int dx[5]={0,1,-1,0,0};
int dy[5]={0,0,0,1,-1};
void spfa(int sx,int sy)
{
    memset(d,63,sizeof(d));d[sx][sy]=st[sx][sy]-'0';
    memset(v,false,sizeof(v));v[sx][sy]=true;
    list[1].x=sx;list[1].y=sy;
    int head=1,tail=2;
    while(head!=tail)
    {
        int x=list[head].x,y=list[head].y;
        for(int i=1;i<=4;i++)
        {
            int tx=x+dx[i],ty=y+dy[i];
            if(tx<1||ty<1||tx>n||ty>m) continue;
            if(d[tx][ty]>d[x][y]+st[tx][ty]-'0')
            {
                d[tx][ty]=d[x][y]+st[tx][ty]-'0';
                if(v[tx][ty]==false)
                {
                    v[tx][ty]=true;
                    list[tail].x=tx;
                    list[tail].y=ty;
                    tail++;if(tail==n*m+1) tail=1;
                }
            }
        }
        v[x][y]=false;
        head++;if(head==n*m+1) head=1;
    }
}
int main()
{
    int t;
    scanf("%d%d%d",&n,&m,&t);
    for(int i=1;i<=n;i++) scanf("%s",st[i]+1);
    double ans=0.0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            spfa(i,j);
            for(int a=1;a<=n;a++)
            {
                for(int b=1;b<=m;b++)
                {
                    if(d[a][b]<=t&&(a!=i||b!=j))
                    {
                        ans=max(ans,sqrt(double((i-a)*(i-a)+(j-b)*(j-b))));
                    }
                }
            }
        }
    }
    printf("%.6lf\n",ans);
    return 0;
}

 

posted @ 2018-03-29 13:05  Star_Feel  阅读(213)  评论(0编辑  收藏  举报