BZOJ 1295: [SCOI2009]最长距离 spfa

1295: [SCOI2009]最长距离

题目连接:

http://www.lydsy.com/JudgeOnline/problem.php?id=1295

Description

windy有一块矩形土地,被分为 N*M 块 1*1 的小格子。 有的格子含有障碍物。 如果从格子A可以走到格子B,那么两个格子的距离就为两个格子中心的欧几里德距离。 如果从格子A不可以走到格子B,就没有距离。 如果格子X和格子Y有公共边,并且X和Y均不含有障碍物,就可以从X走到Y。 如果windy可以移走T块障碍物,求所有格子间的最大距离。 保证移走T块障碍物以后,至少有一个格子不含有障碍物。

Input

输入文件maxlength.in第一行包含三个整数,N M T。 接下来有N行,每行一个长度为M的字符串,'0'表示空格子,'1'表示该格子含有障碍物。

Output

输出文件maxlength.out包含一个浮点数,保留6位小数。

Sample Input

3 3 0

001

001

110

Sample Output

4 3 0

001

001

011

000

Hint

20%的数据,满足 1 <= N,M <= 30 ; 0 <= T <= 0 。

40%的数据,满足 1 <= N,M <= 30 ; 0 <= T <= 2 。

100%的数据,满足 1 <= N,M <= 30 ; 0 <= T <= 30 。

题意

题解:

数据范围只有30*30,我们就可以直接枚举起点,然后对于每个点都跑一边spfa,看究竟这个点移动T个障碍物最多能够到那儿就好了。

然后再暴力更新ans。

代码

#include<bits/stdc++.h>
using namespace std;

int mp[40][40];
char s[40];
int n,m,t;
double ans;
int inq[40][40];
int dis[40][40];
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
struct node
{
    int x,y;
};
void spfa(int x,int y)
{
    memset(inq,0,sizeof(inq));
    node now;now.x=x,now.y=y;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            dis[i][j]=999999;
    dis[x][y]=mp[x][y];
    queue<node> Q;
    Q.push(now);
    inq[x][y]=1;
    while(!Q.empty())
    {
        now=Q.front();
        Q.pop();
        inq[now.x][now.y]=0;
        for(int i=0;i<4;i++)
        {
            node next = now;
            next.x+=dx[i];
            next.y+=dy[i];
            if(next.x<1||next.x>n)continue;
            if(next.y<1||next.y>m)continue;
            if(dis[next.x][next.y]>dis[now.x][now.y]+mp[next.x][next.y])
            {
                if(dis[now.x][now.y]+mp[next.x][next.y]>t)continue;
                dis[next.x][next.y]=dis[now.x][now.y]+mp[next.x][next.y];
                if(!inq[next.x][next.y])
                {
                    Q.push(next);
                    inq[next.x][next.y]=1;
                }
            }
        }
    }
    double tmp = 0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            if(dis[i][j]<=t)
                tmp=max(tmp,sqrt((x-i)*(x-i)+(y-j)*(y-j)));
    ans=max(ans,tmp);
}
void solve()
{
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            spfa(i,j);
}
int main()
{
    scanf("%d%d%d",&n,&m,&t);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s+1);
        for(int j=1;j<=m;j++)
            mp[i][j]=s[j]-'0';
    }
    solve();
    printf("%.6f\n",ans);
}
posted @ 2015-12-21 22:05  qscqesze  阅读(384)  评论(0编辑  收藏  举报