Gym 100851F Froggy Ford(dijkstra)

題意

有條寬爲w的河流,兩岸分別在x = 0, x = w處,河中間有n個石板。在河的一岸有一隻青蛙想通過石板跳到對岸去。現在可以在河
中間某個位置多加一塊石板,使得在單步跳躍中的最大值最小。

思路

Dijkstra變形,用兩維來表示是否路徑中使用過額外的石板。dis[0][u]表示沒使用額外石板的最大最小,dis[1][u]表示使
用額外石板的最大最小。然後就用Dijkstra格式進行轉移了。
/*****************************************
Author      :Crazy_AC(JamesQi)
Time        :2016
File Name   :
*****************************************/
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <map>
#include <set>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <climits>
using namespace std;
#define MEM(x,y) memset(x, y,sizeof x)
#define pk push_back
#define lson rt << 1
#define rson rt << 1 | 1
#define bug cout << "BUG HERE\n"
#define ALL(v) (v).begin(), (v).end()
#define lowbit(x) ((x)&(-x))
#define Unique(x) sort(ALL(x)); (x).resize(unique(ALL(x)) - (x).begin())
#define BitOne(x) __builtin_popcount(x)
#define showtime printf("time = %.15f\n",clock() / (double)CLOCKS_PER_SEC)
#define Rep(i, l, r) for (int i = l;i <= r;++i)
#define Rrep(i, r, l) for (int i = r;i >= l;--i)
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> ii;
typedef pair<ii,int> iii;
const double eps = 1e-8;
const double pi = 4 * atan(1);
const int inf = 1 << 30;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int nCase = 0;
const int maxn = 1e3 + 123;
struct point {
    double x, y;
    void read() {
        scanf("%lf%lf", &x, &y);
    }
    double operator ^ (const point& rhs) {
        return sqrt((x - rhs.x) * (x - rhs.x) + (y - rhs.y) * (y - rhs.y));
    }
}a[maxn];
struct Edge {
    int v, nxt;
    double dis;
}e[maxn*maxn*4];
int head[maxn], ecnt;
void inline addedge(int u,int v,double dis) {
    e[ecnt] = Edge{v, head[u], dis}, head[u] = ecnt++;
    e[ecnt] = Edge{u, head[v], dis}, head[v] = ecnt++;
}
double dis[2][maxn];
int n, w;
struct node {
    int u;
    double md;
    bool used;
    point o;
    bool operator < (const node& rhs) const {
        return md > rhs.md || (md == rhs.md && used > rhs.used);
        // return md > rhs.md;
    }
};
void gao() {
    point ans;
    double m = INF;
    priority_queue<node> que;
    Rep(i, 0, n + 1) dis[0][i] = dis[1][i] = INF;
    que.push(node{0, 0, false, point{0, 0}});
    dis[0][0] = 0;
    while(!que.empty()) {

        node temp = que.top();
        que.pop();

        int u = temp.u;
        if (u == n + 1) {
            printf("%.12lf %.12lf\n", temp.o.x, temp.o.y);
            return ;
            // if (temp.md < m) {
            //     m = temp.md;
            //     ans.x = temp.o.x;
            //     ans.y = temp.o.y;
            // }
            continue;
        }

        for (int i = head[u]; ~i;i = e[i].nxt) {
            int v = e[i].v;
            if (v == 0) continue;
            if (temp.used) {
                if (dis[1][v] > max(temp.md, e[i].dis)) {
                    dis[1][v] = max(temp.md, e[i].dis);
                    que.push(node{v, dis[1][v], true, temp.o});
                }
            }else {
                double x, y;
                //邊界處理,容易錯
                if (u != 0 && v != n + 1) {
                    x = (a[u].x + a[v].x) / 2.0;
                    y = (a[u].y + a[v].y) / 2.0;
                }
                if (u != 0 && v == n + 1) {
                    x = (a[u].x + w) / 2.0;
                    y = a[u].y;
                }
                if (u == 0 && v == n + 1) {
                    x = w / 2.0;
                    y = 0;
                }
                if (u == 0 && v != n + 1) {
                    x = a[v].x / 2.0;
                    y = a[v].y;
                }
                // printf("[%.2lf, %.2lf]\n", x, y);
                if (dis[0][v] > max(temp.md, e[i].dis)) {
                    dis[0][v] = max(temp.md, e[i].dis);
                    que.push(node{v, dis[0][v], false, point{0, 0}});
                }
                if (dis[1][v] > max(temp.md, e[i].dis / 2.0)) {
                    dis[1][v] = max(temp.md, e[i].dis / 2.0);
                    que.push(node{v, dis[1][v], true, point{x, y}});
                }
            }
        }

    }
    printf("%.12lf %.12lf\n", ans.x, ans.y);
}
int main(int argc, const char * argv[])
{    
    // freopen("in.txt","r",stdin);
    // freopen("out.txt","w",stdout);
    freopen("froggy.in","r",stdin);
    freopen("froggy.out","w",stdout);
    while(~scanf("%d%d", &w, &n)) {
        Rep(i, 1, n) a[i].read();
        memset(head, -1, sizeof head), ecnt = 0;
        int vs = 0, vt = n + 1;
        addedge(vs, vt, w);
        Rep(i, 1, n) {
            addedge(vs, i, a[i].x);
            addedge(i, vt, w - a[i].x);
            Rep(j, i + 1, n) {
                addedge(i, j, a[i] ^ a[j]);
            }
        }
        if (n == 0) {
            printf("%.12lf 0\n", w / 2.0);
            continue;
        }
        gao();
    }

    // showtime;
    return 0;
}
發佈了304 篇原創文章 · 獲贊 7 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章