思路:
这题不难,就是有点恶心;
而且,请认真读题目(就是题目卡死劳资);
来,上代码:
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define maxn 807 #define maxm 860005 #define INF 0x7fffffff struct CityType { double x[4],y[4],c; }; struct CityType city[maxn]; int T,n,s,t,head[maxn],E[maxm],V[maxm]; int cnt,que[maxn<<2]; double W[maxm],dis[maxn],c; bool if_[maxn]; inline double d(int now,int v1,int v2) { double x1=city[now].x[v1],x2=city[now].x[v2]; double y1=city[now].y[v1],y2=city[now].y[v2]; return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2); } inline void edge_add(int u,int v,double w) { E[++cnt]=head[u],V[cnt]=v,W[cnt]=w,head[u]=cnt; E[++cnt]=head[v],V[cnt]=u,W[cnt]=w,head[v]=cnt; } double ds(int u,int v1,int v,int v2) { double xx=city[u].x[v1]-city[v].x[v2]; double yy=city[u].y[v1]-city[v].y[v2]; return sqrt(xx*xx+yy*yy); } void spfa() { memset(if_,false,sizeof(if_)); memset(dis,0x7f,sizeof(dis)); int h=0,tail=4;que[0]=s*4-3,que[1]=s*4-2; que[2]=s*4-1,que[3]=s*4,if_[s*4-3]=true; if_[s*4-2]=true,if_[s*4-1]=true,if_[s*4]=true; dis[s*4-3]=0,dis[s*4-2]=0,dis[s*4-1]=0,dis[s*4]=0; while(h<tail) { int now=que[h++];if_[now]=false; for(int i=head[now];i;i=E[i]) { if(dis[V[i]]>dis[now]+W[i]) { dis[V[i]]=dis[now]+W[i]; if(!if_[V[i]]) if_[V[i]]=true,que[tail++]=V[i]; } } } } int main() { scanf("%d",&T); while(T--) { memset(head,0,sizeof(head)),cnt=0; scanf("%d%lf%d%d",&n,&c,&s,&t); for(int i=1;i<=n;i++) { for(int v=0;v<3;v++) scanf("%lf%lf",&city[i].x[v],&city[i].y[v]); scanf("%lf",&city[i].c); double d01=d(i,0,1),d02=d(i,0,2),d12=d(i,1,2); int pos=i*4-3; if(d01+d02==d12) { city[i].x[3]=city[i].x[1]+city[i].x[2]-city[i].x[0]; city[i].y[3]=city[i].y[1]+city[i].y[2]-city[i].y[0]; } else if(d01+d12==d02) { city[i].x[3]=city[i].x[0]+city[i].x[2]-city[i].x[1]; city[i].y[3]=city[i].y[0]+city[i].y[2]-city[i].y[1]; } else { city[i].x[3]=city[i].x[0]+city[i].x[1]-city[i].x[2]; city[i].y[3]=city[i].y[0]+city[i].y[1]-city[i].y[2]; } for(int j=0;j<=3;j++) { for(int v=j+1;v<=3;v++) edge_add(pos+j,pos+v,sqrt(d(i,j,v))*city[i].c); } } for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { int posi=i*4-3,posj=j*4-3; for(int v=0;v<4;v++) { for(int z=0;z<4;z++) edge_add(v+posi,z+posj,ds(i,v,j,z)*c); } } } spfa();double ans=INF; for(int i=0;i<=3;i++) ans=min(ans,dis[i+t*4-3]); printf("%.1lf",ans); } return 0; }