BZOJ#1295[SCOI2009]最长距离

[SCOI2009]最长距离

思路:

将1的格子变成边权为1,则需要求每个点所能到达的点的最短距离并且不超过t,这里采用01bfs求最短路

代码:

#include <bits/stdc++.h>
#define int long long
int _ = 0, Case = 1;
using namespace std;
#define all(v) begin(v),end(v)
#define nline '\n'
const int N = 40;
int d[N][N];
char s[N][N];
int n, m, t;
struct T {
    int x, y, w;
};
bool vis[N][N];
pair<int, int> moves[] = {{ -1, 0}, {0, -1}, {0, 1}, {1, 0}}; //ULRD
double dist(int x, int y, int a, int b) {
    int ta = abs(x - a);
    int tb = abs(y - b);
    return sqrt(ta*ta + tb*tb);
}
double bfs(int x, int y) {
    deque<T> q;
    q.push_front({x, y, 0});
    memset(d, 0x3f, sizeof d);
    d[x][y] = 0;
    memset(vis,0,sizeof vis);
    while (q.size()) {
        auto [x, y, w] = q.front();
        q.pop_front();
        if (vis[x][y]) continue;
        vis[x][y] = true;
        for (auto [dx, dy] : moves) {
            int tx = x + dx, ty = dy + y;
            if (tx >= 1 and tx <= n and ty >= 1 and ty <= m) {
                int nw = 0;
                if (s[tx][ty] == '1') nw = 1;
                if (d[tx][ty] > w + nw) {
                    d[tx][ty]=w+nw;
                    if (nw) {
                        q.push_back({tx, ty, w + nw});
                    } else {
                        q.push_front({tx, ty, w + nw});
                    }
                }
            }
        }
    }
    double res = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (d[i][j]<=t) {
                res = max(res, dist(x, y, i, j));
            }
        }
    }

    return res;
}
void solve(int Case) {
    scanf("%lld%lld%lld",&n,&m,&t);
    double res=0;
    for (int i = 1; i <= n; i++) scanf("%s",(s[i]+1));
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (s[i][j] == '0') {
                res = max(res, bfs(i, j));

            }
        }
    }
    printf("%.6lf\n",res);
}

signed main() {
    //ios::sync_with_stdio(false); cin.tie(nullptr);
//     cin >> _; for (Case = 1; Case <= _; Case++)
    solve(Case);

    return 0;
}
posted @ 2022-04-02 15:53  指引盗寇入太行  阅读(19)  评论(0编辑  收藏  举报