G - Easy Glide ( Gym - 103687G)完全无向图求最短路

直接用输入顺序的下标来映射输入的横纵坐标值,因为这个图是个完全无向图,所以计算出每两点之间所使用的时间,的然后跑一遍dijstra求最短时间即可。有一个坑是double类型的变量不能用memset进行赋值,用for循环才能实现。因为是无向图,链式前向星的e数组,边数数组和权值数组要开两倍的空间。完全图的建图方法,方法如下。

for (int i = 1; i <n; i++)
	{
		for (int j = i + 1; j <= n; j++)
		{
            
			add(i, j);
			//add(j, i);(无向图)
		}
	}

ac代码

#include<iostream>
#include<queue>
#include<math.h>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
#include<set>
const int N = 1e6 + 10;
const int M = 4 * N;
#define mod 192600817
#define int  long long
#define FAST ios::sync_with_stdio(false);
#define endl '\n'
#define rep(i,n)for(int i=1;i<=n;++i)
#define sc(n) scanf("%d",&n);
using namespace std;
const int INF = 1e16;
typedef pair<double, int>PII;
int a[N],b[N];
int e[N*2], h[N],ne[N*2],cnt;
double w[N*2];
double dist[N];
int n,s,ss,t,tt,p1,p2;
bool st[N];
void dijstra()
{
    for(int i=1;i<=n;i++)dist[i]=0x3f3f3f3f;
    memset(st,false,sizeof st);
    dist[0]=0;
    priority_queue<PII,vector<PII>,greater<PII>>q;
    q.push({0,0});
    while(q.size())
    {
        auto t=q.top();
        q.pop();
        int ver=t.second;
        if(st[ver])continue;
        st[ver]=true;
        for(int i=h[ver];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(dist[j]>dist[ver]+w[i])
            {
                dist[j]=dist[ver]+w[i];
                q.push({dist[j],j});
            }
        }
    }
}

void add(int a,int b,double c)
{
    e[cnt]=b,w[cnt]=c,ne[cnt]=h[a],h[a]=cnt++;
}

signed main()
{
    FAST;
    memset(h,-1,sizeof h);
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i] >> b[i];
	}
	cin >> s >> ss >> t >> tt;
	cin>>p1>>p2;
	a[0] = s;
	b[0] = ss;
	n++;
	a[n] = t;
	b[n] = tt;
	for (int i = 0; i <= n; i++)
	{
		for (int j = i + 1; j <= n; j++)
		{
		    double di=(double)sqrt((a[i]-a[j])*(a[i]-a[j])+(b[i]-b[j])*(b[i]-b[j]));
		    double ti=di/p2;
		    if(ti>3)ti=(double)3+(di-3*p2)/p1;
            double ti2=(double)di/p1;
            if(i)add(i,j,ti);//起点到任意点不会有加速过程
            else if(i==0)add(i,j,ti2);
            if(j!=n)add(j,i,ti);
            else if(j==n)add(j,i,ti2);
		}
	}
   dijstra();
   printf("%.12lf\n",dist[n]);
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值