B1295 [SCOI2009]最长距离 最短路

就是一道最短路的裸题,直接跑spfa就行了。(spfa死了)

最后在答案处判断是否障碍物太多,然后就直接找最大值就行。

(数据特别水,我错误算法60)

题干:

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
【输入样例二】
4 3 0
001
001
011
000
【输入样例三】
3 3 1
001
001
001
Sample Output
【输出样例一】
1.414214
【输出样例二】
3.605551
【输出样例三】
2.828427
HINT
20%的数据,满足 1 <= N,M <= 300 <= T <= 040%的数据,满足 1 <= N,M <= 300 <= T <= 2100%的数据,满足 1 <= N,M <= 300 <= T <= 30

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(int i = a;i <= n;i++)
#define lv(i,a,n) for(int i = a;i >= n;i--)
#define clean(a) memset(a,0,sizeof(a))
const int INF = 1 << 30;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
        if(c == '-') op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
        x = x * 10 + c - '0';
    if(op) x = -x;
}
template <class T>
void write(T x)
{
    if(x < 0) putchar('-'), x = -x;
    if(x >= 10) write(x / 10);
    putchar('0' + x % 10);
}
int n,m,t;
int dx[5] = {0,0,-1,1};
int dy[5] = {1,-1,0,0};
int dis[40][40],a[40][40],mp[40][40];
bool inq[40][40];
bool p[40][40];
char s[40];
db ans = 0;
struct node
{
    int x,y;
}q[100010];
void getans(int x,int y)
{
    duke(i,x,n)
    {
        duke(j,1,m)
        {
            if(dis[i][j] <= t && (y - j) * (y - j) + (x - i) * (x - i) > ans)
            ans = (y - j) * (y - j) + (x - i) * (x - i);
        }
    }
}
void spfa(int x,int y)
{
    int nowx,nowy,t = 1,w = 2,nx,ny;
    q[1].x = x;q[1].y = y;
    clean(inq);
    memset(dis,127,sizeof(dis));
    inq[x][y] = 1;
    dis[x][y] = mp[x][y];
    while(t <= w)
    {
        nowx = q[t].x;nowy = q[t].y;
        t++;
        for(int i = 0;i < 4;i++)
        {
            nx = nowx + dx[i];
            ny = nowy + dy[i];
            if(nx > n || nx < x || ny > m || ny < 1)
            continue;
            if(dis[nowx][nowy] + mp[nx][ny] < dis[nx][ny])
            {
                dis[nx][ny] = dis[nowx][nowy] + mp[nx][ny];
                if(!inq[nx][ny])
                {
                    q[++w].x = nx;
                    q[w].y = ny;
                    inq[nx][ny] = 1;
                }
            }
        }
        inq[nowx][nowy] = 0;
    }
    getans(x,y);
}
int main()
{
    read(n);read(m);read(t);
    duke(i,1,n)
    {
        scanf("%s",s);
        duke(j,0,m - 1)
        mp[i][j + 1] = s[j] - '0';
    }
    duke(i,1,n)
    {
        duke(j,1,m)
        {
            spfa(i,j);
        }
    }
    printf("%.6lf",sqrt(ans));
    return 0;
}
/*
3 3 0
001
001
110
*/

 

posted @ 2018-09-16 22:19  DukeLv  阅读(202)  评论(0编辑  收藏  举报