几何+最短路
我们根据已给的三个坐标,通过勾股定理,确认第四个点,然后SPFA时判断是不是同一个城市就行了
代码
//By AcerMo
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=1050;
int w[M];
bool vis[M];
int n,m,st,ed;
double dis[M];
int x[M],y[M],id[M],cnt;
inline int read()
{
int x=0;char ch=getchar();
while (ch>'9'||ch<'0') ch=getchar();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x;
}
inline int calc(int x,int y)
{
return (x-y)*(x-y);
}
inline void get4(int i)
{
int a=calc(x[cnt],x[cnt-1])+calc(y[cnt],y[cnt-1]);
int b=calc(x[cnt],x[cnt-2])+calc(y[cnt],y[cnt-2]);
int c=calc(x[cnt-1],x[cnt-2])+calc(y[cnt-1],y[cnt-2]);
int x4,y4;
if (a+b==c) x4=x[cnt-1]+x[cnt-2]-x[cnt],y4=y[cnt-1]+y[cnt-2]-y[cnt];
if (a+c==b) x4=x[cnt]+x[cnt-2]-x[cnt-1],y4=y[cnt]+y[cnt-2]-y[cnt-1];
if (b+c==a) x4=x[cnt]+x[cnt-1]-x[cnt-2],y4=y[cnt]+y[cnt-1]-y[cnt-2];
x[++cnt]=x4;y[cnt]=y4;id[cnt]=i;
return ;
}
inline void SPFA()
{
fill(dis,dis+M,2e9);
queue<int>q;dis[st*4]=dis[st*4-1]=dis[st*4-2]=dis[st*4-3]=0;
q.push(st*4),q.push(st*4-1),q.push(st*4-2),q.push(st*4-3);
while (q.size())
{
int u=q.front();q.pop();vis[u]=0;
for (int i=1;i<=4*n;i++)
{
if (i==u) continue;
double cost=(double)sqrt(calc(x[u],x[i])+calc(y[u],y[i]));
if (id[u]==id[i]) cost*=(double)w[id[i]];
else cost*=(double)m;
if (dis[i]>dis[u]+cost)
{
dis[i]=dis[u]+cost;
if (!vis[i])
vis[i]=1,q.push(i);
}
}
}
return ;
}
signed main()
{
int t=read();
while (t--)
{
n=read();m=read();st=read();ed=read();
for (int i=1;i<=n;i++)
{
x[++cnt]=read(),y[cnt]=read();id[cnt]=i;
x[++cnt]=read(),y[cnt]=read();id[cnt]=i;
x[++cnt]=read(),y[cnt]=read();id[cnt]=i;
get4(i);w[i]=read();id[cnt]=i;
}
SPFA();double ans=2e9;
for (int i=0;i<=3;i++)
ans=min(ans,dis[ed*4-i]);
printf("%.1lf\n",ans);
}
return 0;
}