直接用输入顺序的下标来映射输入的横纵坐标值,因为这个图是个完全无向图,所以计算出每两点之间所使用的时间,的然后跑一遍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]);
}