数据都造不出来,只能对着题解盯
#include<bits/stdc++.h>
using namespace std;
constexpr int N=505,M=1e5+5;
constexpr double pi=acos(-1),eps=1e-9;
namespace _3D_VECTOR{
struct Vector{
double x,y,z;
Vector(double xx=0,double yy=0,double zz=0){x=xx,y=yy,z=zz;}
};
void write(Vector v){cerr<<v.x<<' '<<v.y<<' '<<v.z<<endl;}
Vector operator + (Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y,a.z+b.z);}
Vector operator - (Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y,a.z-b.z);}
double operator * (Vector a,Vector b){return a.x*b.x+a.y*b.y+a.z*b.z;}
Vector operator / (Vector a,Vector b){return Vector(a.y*b.z-a.z*b.y,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x);}
double operator ! (Vector a){return sqrtl(a.x*a.x+a.y*a.y+a.z*a.z);}
}
using namespace _3D_VECTOR;
int n,m,L,s,t;
double R,K,q[N];
Vector tower[N];
struct wire{
int v;
double c,quad,cosine;
Vector cross;
};
vector<wire> e[N];
bool comp(wire a,wire b){
double alpha=atan2(a.quad,a.cosine);
double beta=atan2(b.quad,b.cosine);
return alpha<beta;
}
struct Graph{
struct edge{
int from,to,nx,reg,rev;
bool spe,lr;
double c;
}e[M*2];
int head[M],tot=1;
void add_edge(int u,int v,double c){
e[++tot]={u,v,head[u],-1,-1,0,0,c};
head[u]=tot;
}
}G1,G2;
#define repg(G,i,u,v) for(int i=G.head[u],v=G.e[i].to;i;i=G.e[i].nx,v=G.e[i].to)
int regtot,ano[N][N];
inline int id(int regid,int floor,int oe){return (floor*(regtot+n)+regid-1)*2+oe;}
inline tuple<int,int,int> decode(int x){
int oe=x%2;
x=(x-oe)/2;
int floor=x/(regtot+n);
int regid=x%(regtot+n)+1;
return tuple<int,int,int>(regid,floor,oe);
}
bool vis[M],spe_pt[N];
set<int> start;
inline bool dfs(int u,int t){
vis[u]=1;
if(u==t)return spe_pt[u]=1;
repg(G1,i,u,v){
if(vis[v])continue;
if(dfs(v,t)){
spe_pt[u]=1;
G1.e[i].spe=1;
G1.e[G1.e[i].rev].spe=1;
G1.e[i].lr=1;
return 1;
}
}
return 0;
}
double dis[M];
typedef pair<double,int> pdi;
int _pre[M];
inline void DIJ(int s){
for(int i=0;i<=id(regtot,L,1);i++)dis[i]=1e14,vis[i]=0,_pre[i]=-1;
dis[s]=0;
_pre[s]=-1;
priority_queue<pdi,vector<pdi>,greater<pdi> > Q;
Q.push(pdi(0,s));
while(!Q.empty()){
int u=Q.top().second;
Q.pop();
if(vis[u])continue;
vis[u]=1;
repg(G2,e0,u,v){
if(dis[u]+G2.e[e0].c<dis[v]){
dis[v]=dis[u]+G2.e[e0].c;
_pre[v]=u;
Q.push(pdi(dis[v],v));
}
}
}
}
void write(int x){
if(~_pre[x])write(_pre[x]);
auto tu1=decode(x);
cout<<get<0>(tu1)<<' '<<get<1>(tu1)<<' '<<get<2>(tu1)<<'|';
}
int main(){
freopen("P9972.in","r",stdin);
freopen("P9972.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>L>>s>>t>>R>>K;
for(int i=1;i<=n;i++){
double a,b,theta,phi;
cin>>a>>b>>q[i];
theta=a*pi,phi=b*pi;
tower[i]=Vector(R*sin(theta)*cos(phi),R*sin(theta)*sin(phi),R*cos(theta));
}
for(int i=1,u,v;i<=m;i++){
cin>>u>>v;
double r=R*acos(tower[u]*tower[v]/!tower[u]/!tower[v]);
e[u].push_back((wire){v,K*q[u]*q[v]/r/r});
e[v].push_back((wire){u,K*q[u]*q[v]/r/r});
}
for(int i=1;i<=n;i++){
if(e[i].empty())continue;
Vector u=tower[i],base=u/tower[e[i][0].v];
for(wire &j:e[i]){
j.cross=u/tower[j.v];
j.cosine=base*j.cross/!base/!j.cross;
Vector para_u=base/j.cross;
if(u.x>eps)j.quad=para_u.x/u.x;
else if(u.y>eps)j.quad=para_u.y/u.y;
else j.quad=para_u.z/u.z;
}
sort(e[i].begin(),e[i].end(),comp);
}
for(int i=1;i<=n;i++){
for(wire j:e[i]){
// cout<<i<<' '<<j.v<<endl;
G1.add_edge(i,j.v,j.c);
G1.e[G1.tot].rev=ano[j.v][i];
G1.e[ano[j.v][i]].rev=G1.tot;
ano[i][j.v]=G1.tot;
}
}
// for(int i=2;i<=G1.tot;i++)cout<<i<<' '<<G1.e[i].from<<' '<<G1.e[i].to<<' '<<G1.e[i].nx<<' '<<G1.e[i].rev<<endl;
regtot=n;
for(int i=1;i<=n;i++){
repg(G1,k,i,j){
if(~G1.e[k].reg)continue;
++regtot;
int k0=k;
while(1){
G1.e[k0].reg=regtot;
if(G1.e[k0].to==i)break;
k0=G1.e[G1.e[k0].rev].nx?G1.e[G1.e[k0].rev].nx:G1.head[G1.e[k0].to];
}
// for(int i=2;i<=G1.tot;i++)cout<<G1.e[i].from<<' '<<G1.e[i].to<<' '<<G1.e[i].reg<<endl;
// cout<<"asdf"<<endl;
}
}
dfs(s,t);
memset(vis,0,sizeof(vis));
// for(int i=2;i<=G1.tot;i++)if(G1.e[i].spe)cout<<G1.e[i].from<<' '<<G1.e[i].to<<endl;
for(int i=2;i<=G1.tot;i++){
auto [from,to,nx,reg1,rev,spe,lr,c]=G1.e[i];
int reg2=G1.e[rev].reg;
for(int j=0;j<=L;j++){
for(int k:{0,1}){
G2.add_edge(id(reg1,j,k),id(reg2,j,k^spe),c);
G2.add_edge(id(to,j,k),id(reg1,j,k^spe&lr),0);
if(j<L&&to!=s&&to!=t)G2.add_edge(id(reg1,j,k),id(to,j+1,k^spe&lr),0);
}
}
}
// for(int i=2;i<=G2.tot;i++){
// cout<<"edge:"<<i<<endl;
// auto tu1=decode(G2.e[i].from),tu2=decode(G2.e[i].to);
// cout<<get<0>(tu1)<<' '<<get<1>(tu1)<<' '<<get<2>(tu1)<<endl;
// cout<<get<0>(tu2)<<' '<<get<1>(tu2)<<' '<<get<2>(tu2)<<endl;
// cout<<G2.e[i].c<<endl;
// }
for(int i=1;i<=n;i++)if(spe_pt[i])repg(G2,k,id(i,0,0),j)start.insert(j&((1<<30)-2));
double ans=1e15;
for(int st:start){
auto tu1=decode(st);
int termi=id(get<0>(tu1),L,1);
// cout<<get<0>(tu1)<<' '<<get<1>(tu1)<<' '<<get<2>(tu1)<<endl;
DIJ(st);
ans=min(ans,dis[termi]);
// write(termi);cout<<endl;
}
cout<<fixed<<setprecision(15)<<ans;
return 0;
}