ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

GYM100851 F - Froggy Ford(最短路铜牌题)

2022-09-04 14:03:56  阅读:137  来源: 互联网

标签:dis1 dis2 int double rep Ford Froggy max GYM100851


题意:

​ 现在有一条河,河中有n个石头,你需要从河的一端到河的另一端。现在你有一次机会在任意位置放置一个石头,请问石头放在哪里可以使过河的最长路径最短。请输出放置的石头坐标。

思路:

​ n的规模是\(1e3\),所以可以做到\(n^2\)的算法,我们把起点和终点也当做一块石头,基于贪心的思想,可以知道使最长路径最短的放法一定是在两个石子的中间点放。先预处理出起点到各个点的最短路和终点反跑到各个点的最短路,然后\(n^2\)枚举两个石头间距并将其缩短一半,更新答案。

#include <bits/stdc++.h>
    
using namespace std;
#define rep(i, a, n) for(int i = a; i < n; i++)
#define all(x) x.begin(), x.end()
#define pb push_back
#define ios ios::sync_with_stdio(false);cin.tie(0);
#define debug(x)    cout << x << endl;
#define SZ(x)    (int)x.size()
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
const int inf = 0x3f3f3f3f;
const double INF = 1e20;
void read(int &x) {int s = 0, f = 1; char ch = getchar(); while(!isdigit(ch)) {f = (ch == '-' ? -1 : f); ch = getchar();} while(isdigit(ch)) {s = s * 10 + ch - '0'; ch = getchar();} x = s * f;}

const int N = 1005;
struct node {
    double val;
    int id;
    bool operator < (const node& a) const {
        return val > a.val;
    }
};

double e[N][N];
double x[N], y[N];
double dis1[N], dis2[N];
int vis[N];
int n;
double ww;

double dis(double a, double b, double c, double d)
{
    return sqrt((b - a) * (b - a) + (d - c) * (d - c));
}

void dij1(int st)
{
    priority_queue<node> q;
    rep(i, 1, n + 1)    dis1[i] = INF;
    memset(vis, 0, sizeof vis);
    dis1[st] = 0;
    q.push({dis1[st], st});
    while(q.size())
    {
        node tmp = q.top();
        q.pop();

        int u = tmp.id;
        double dist = tmp.val;
        if(vis[u])  continue;
        vis[u] = 1;
        rep(v, 1, n + 1)
        {
            if(u == v)  continue;
            if(!vis[v] && dis1[v] > max(dist, e[u][v]))
            {
                dis1[v] = max(dist, e[u][v]);
                q.push({dis1[v], v});
            }
        }
    } 
}

void dij2(int st)
{
    priority_queue<node> q;
    rep(i, 1, n + 1)    dis2[i] = INF;
    memset(vis, 0, sizeof vis);
    dis2[st] = 0;
    q.push({dis2[st], st});
    while(q.size())
    {
        node tmp = q.top();
        q.pop();

        int u = tmp.id;
        double dist = tmp.val;
        if(vis[u])  continue;
        vis[u] = 1;
        rep(v, 1, n + 1)
        {
            if(u == v)  continue;
            if(!vis[v] && dis2[v] > max(dist, e[u][v]))
            {
                dis2[v] = max(dist, e[u][v]);
                q.push({dis2[v], v});
            }
        }
    } 
}

signed main()
{
    freopen("froggy.in", "r", stdin);
    freopen("froggy.out", "w", stdout);
    scanf("%lf%d", &ww, &n);
    if(n == 0)
        printf("%.3lf %.3lf\n", ww / 2.0, 0.0);
    else
    {
        rep(i, 2, n + 2)
            scanf("%lf %lf", &x[i], &y[i]);
        n += 2; //1是起点,n是终点
        e[1][n] = e[n][1] = ww;
        rep(i, 2, n)
        {
            e[1][i] = e[i][1] = x[i];
            e[n][i] = e[i][n] = ww - x[i];
        }
        rep(i, 2, n)
        rep(j, i + 1, n)
            e[i][j] = e[j][i] = dis(x[i], x[j], y[i], y[j]);

        dij1(1);
        dij2(n);

        double res = INF;
        double resx, resy;
        rep(i, 2, n)
        rep(j, 2, n)
        {
            if(i == j)  continue;
            if(res > max(e[i][j] / 2.0, max(dis1[i], dis2[j])))
            {
                res = max(e[i][j] / 2.0, max(dis1[i], dis2[j]));
                resx = (x[i] + x[j]) / 2.0, resy = (y[i] + y[j]) / 2.0;
            }
        }   

        rep(i, 2, n)
        {
            if(res > max(x[i] / 2.0, dis2[i]))
            {
                res = max(x[i] / 2.0, dis2[i]);
                resx = x[i] / 2.0, resy = y[i];
            }
            if(res > max((ww - x[i]) / 2.0, dis1[i]))
            {
                res = max((ww - x[i]) / 2.0, dis1[i]);
                resx = x[i] + (ww - x[i]) / 2.0, resy = y[i];
            }
        }
        printf("%.3lf %.3lf\n", resx, resy);
    }
}

标签:dis1,dis2,int,double,rep,Ford,Froggy,max,GYM100851
来源: https://www.cnblogs.com/DM11/p/16654955.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有