题目链接:https://www.luogu.com.cn/problem/P1027
将每个机场看作一个点,确定(x4,y4),用平移的方法,然后判断A、B是否为同一个城市,如果是同一个,用铁路价格;否则用飞机价格。
最后找B城市内4个机场dis最小的。
AC代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<queue> 5 #include<cmath> 6 using namespace std; 7 struct node{ 8 int x,y,city; 9 }a[405]; 10 double dis[405]; 11 int T[405],vis[405]; 12 int s,t,A,B,n; 13 void init(){ 14 memset(a,0,sizeof(a)); 15 } 16 int distance(int x1,int y1,int x2,int y2){ 17 return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2); 18 } 19 void get(int x1,int y1,int x2,int y2,int x3,int y3,int n){ 20 int ab=distance(x1,y1,x2,y2); 21 int bc=distance(x2,y2,x3,y3); 22 int ac=distance(x1,y1,x3,y3); 23 if(ab+bc==ac) a[n+3].x=x1-x2+x3,a[n+3].y=y1-y2+y3; 24 else if(ac+bc==ab) a[n+3].x=x1-x3+x2,a[n+3].y=y1-y3+y2; 25 else a[n+3].x=x3-x1+x2,a[n+3].y=y3-y1+y2; 26 } 27 void spfa(){ 28 queue<int> q; 29 for(int i=1;i<=s*4;i++) dis[i]=99999999.99; 30 for(int i=A*4-3;i<=A*4;i++){dis[i]=0;q.push(i);vis[i]=1;} 31 while(!q.empty()){ 32 int u=q.front();q.pop();vis[u]=0; 33 for(int i=1;i<=4*s;i++){ 34 if(i==u) continue; 35 double cost=sqrt(distance(a[u].x,a[u].y,a[i].x,a[i].y)); 36 if(a[i].city==a[u].city) cost*=T[a[i].city]; 37 else cost*=t; 38 if(dis[u]+cost<dis[i]){ 39 dis[i]=dis[u]+cost; 40 if(!vis[i]){vis[i]=1;q.push(i);} 41 } 42 } 43 } 44 } 45 int main(){ 46 scanf("%d",&n); 47 while(n--){ 48 scanf("%d%d%d%d",&s,&t,&A,&B); 49 for(int i=1;i<=s*4;i+=4){ 50 scanf("%d%d%d%d%d%d%d",&a[i].x,&a[i].y,&a[i+1].x,&a[i+1].y,&a[i+2].x,&a[i+2].y,&T[i/4+1]); 51 get(a[i].x,a[i].y,a[i+1].x,a[i+1].y,a[i+2].x,a[i+2].y,i); 52 a[i].city=a[i+1].city=a[i+2].city=a[i+3].city=i/4+1; 53 } 54 spfa(); 55 double ans=dis[B*4]; 56 for(int i=B*4-3;i<B*4;i++) if(dis[i]<ans) ans=dis[i]; 57 printf("%.1lf",ans); 58 } 59 return 0; 60 }