• Gym100851F Froggy Ford 最短路变形


    网址:https://codeforces.com/gym/100851

    题意:

    在一段宽度为$w$的河上有$n$个石头,石头的位置确定,用坐标$(x,y)$表示,河左岸的方程是$x=0$,右岸的方程是$x=w$,有一只青蛙将从左岸沿着这些石头跳到右岸(不借助石头也可以),现在打算在这条河上再加一个石头,求出新的石头的位置,使得在加上这个石头后,青蛙通过这条河时路径上的跳跃的最大长度最小。

    题解:

    这个题也是套路题了,河的左岸和右岸一定是当成一点起点和一个终点。然后我们预处理出起点和终点到每个石头上的路径的边权最大值,用$dijkstra$求即可,转移方程是$dis[v]=max(dis[u],cur_edge)$。求的时候需要重新建图,因为不能从一个石头跳到起点终点,再跳到另一个石头上。建完图之后我们求出了$diss和dist$。然后我们就求$min(max(diss[u],e(u->v),dist[v]))$,找到这个$u,v$。

    有$4$种情况:

    $u=$起点,$v!=$终点,则这个石头的坐标是$(frac{x_v}{2},y)$。

    $v=$终点,$u!=$起点,则这个石头的坐标是$(frac{w+x_u}{2},y)$。

    $u=$起点,$v=$终点,则这个石头的坐标是$(frac{w}{2},0)$。

    其他,则这个石头的坐标是$(frac{x_u+x_v}{2},frac{y_u+y_v}{2})$。

    AC代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e3 + 5;
    typedef long long ll;
    pair<double, double>p[N];
    int n;
    double w;
    struct edge
    {
    	int to;
    	double w;
    	bool operator <(const edge& a)const
    	{
    		return w > a.w;
    	}
    };
    vector<edge>G[N];
    double len(pair<double, double>& a, pair<double, double>& b)
    {
    	return sqrt((a.first - b.first) * (a.first - b.first) +
    		(a.second - b.second) * (a.second - b.second));
    }
    double dist[N], diss[N];
    bool vis[N];
    void dijkstra(int s, double* dis)
    {
    	priority_queue<edge>q;
    	for (int i = 0; i <= n + 1; ++i)
    		dis[i] = 0x3f3f3f3f3f3f3f3f;
    	memset(vis, 0, sizeof(vis));
    	q.push({ s,0 });
    	dis[s] = 0;
    	while (q.size())
    	{
    		edge cur = q.top();
    		q.pop();
    		if (vis[cur.to])
    			continue;
    		vis[cur.to] = 1;
    		for (auto i : G[cur.to])
    			if (max(dis[cur.to], i.w) < dis[i.to])
    			{
    				dis[i.to] = max(dis[cur.to], i.w);
    				q.push({ i.to,dis[i.to] });
    			}
    	}
    }
    void init1()
    {
    	for (int i = 0; i <= n + 1; ++i)
    		G[i].clear();
    	for (int i = 1; i <= n; ++i)
    	{
    		G[0].push_back({ i,p[i].first });
    		G[i].push_back({ n + 1,w - p[i].first });
    	}
    	for (int i = 1; i <= n; ++i)
    		for (int j = i + 1; j <= n; ++j)
    		{
    			double d = len(p[i], p[j]);
    			G[i].push_back({ j,d });
    			G[j].push_back({ i,d });
    		}
    }
    void init2()
    {
    	for (int i = 0; i <= n + 1; ++i)
    		G[i].clear();
    	for (int i = 1; i <= n; ++i)
    	{
    		G[n + 1].push_back({ i,w - p[i].first });
    		G[i].push_back({ 0,p[i].first });
    	}
    	for (int i = 1; i <= n; ++i)
    		for (int j = i + 1; j <= n; ++j)
    		{
    			double d = len(p[i], p[j]);
    			G[i].push_back({ j,d });
    			G[j].push_back({ i,d });
    		}
    }
    int main()
    {
    #ifndef _Aya
    	freopen("froggy.in", "r", stdin);
    	freopen("froggy.out", "w", stdout);
    #endif
    	scanf("%lf%d", &w, &n);
    	for (int i = 1; i <= n; ++i)
    		scanf("%lf%lf", &p[i].first, &p[i].second);
    	init1();
    	dijkstra(0, diss);
    	init2();
    	dijkstra(n + 1, dist);
    	double maxn = 0x3f3f3f3f3f3f3f3f;
    	double ansx = 0, ansy = 0;
    	for (int i = 0; i <= n + 1; ++i)
    		for (int j = 0; j <= n + 1; ++j)
    		{
    			double tmp;
    			if (i == j)
    				continue;
    			if (i == 0 && j == n + 1)
    				tmp = w;
    			else if (i == 0)
    				tmp = p[j].first;
    			else if (j == n + 1)
    				tmp = w - p[i].first;
    			else
    				tmp = len(p[i], p[j]);
    			if (maxn > max(max(diss[i], tmp / 2), max(tmp / 2, dist[j])))
    			{
    				maxn = max(max(diss[i], tmp / 2), max(tmp / 2, dist[j]));
    				if (i == 0 && j != n + 1)
    					ansx = p[j].first / 2, ansy = p[j].second;
    				else if (i != 0 && j == n + 1)
    					ansx = (p[i].first + w) / 2, ansy = p[i].second;
    				else if (i == 0 && j == n + 1)
    					ansx = w / 2, ansy = 0;
    				else
    					ansx = (p[i].first + p[j].first) / 2, ansy = (p[i].second + p[j].second) / 2;
    			}
    		}
    	printf("%lf %lf
    ", ansx, ansy);
    	return 0;
    }
    /*
    10 7
    2 2
    2 4
    5 1
    5 3
    8 2
    7 5
    9 4
    */
    
  • 相关阅读:
    Day3学习笔记
    Day2学习笔记
    Day1学习笔记
    中文标识
    about original idea
    那些和matlab有关的
    GRE Sub math 报名
    虽然实际没有什么用,但是可能会有理论上的意义吧
    latex相关
    对venturelli theorem的重新认识
  • 原文地址:https://www.cnblogs.com/Aya-Uchida/p/12589257.html
Copyright © 2020-2023  润新知