zoukankan      html  css  js  c++  java
  • 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
    */
  • 相关阅读:
    hdu 1455 N个短木棒 拼成长度相等的几根长木棒 (DFS)
    hdu 1181 以b开头m结尾的咒语 (DFS)
    hdu 1258 从n个数中找和为t的组合 (DFS)
    hdu 4707 仓鼠 记录深度 (BFS)
    LightOJ 1140 How Many Zeroes? (数位DP)
    HDU 3709 Balanced Number (数位DP)
    HDU 3652 B-number (数位DP)
    HDU 5900 QSC and Master (区间DP)
    HDU 5901 Count primes (模板题)
    CodeForces 712C Memory and De-Evolution (贪心+暴力)
  • 原文地址:https://www.cnblogs.com/DukeLv/p/9657761.html
Copyright © 2011-2022 走看看