• 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
    */
  • 相关阅读:
    春节不回家
    夜间突然发烧,无法入眠
    歌词写得真好
    近日看到网上许多BBS寻找SAP及ABAP程序的学习资料,本人深知学习的艰辛与不易,特贡献自己多年的学习资料,完全免费
    人生的真谛
    SMARTFORMS的调用方法(作者:曹玉平)
    自己给自己当医生
    将ocx添加到.NET
    AQtime + ocx/dll
    ActiveX:创建安装:
  • 原文地址:https://www.cnblogs.com/DukeLv/p/9657761.html
Copyright © 2020-2023  润新知