https://www.luogu.org/problem/P1027
又到暑假了,住在城市A的Car想和朋友一起去城市B旅游。她知道每个城市都有4个飞机场,分别位于一个矩形的4个顶点上,同一个城市中2个机场之间有1条笔直的高速铁路,第I个城市中高速铁路了的单位里程价格为Ti,任意两个不同城市的机场之间均有航线,所有航线单位里程的价格均为t。
题目描述
图例(从上而下)
机场
高速铁路
飞机航线
注意:图中并没有标出所有的铁路与航线。
那么Car应如何安排到城市B的路线才能尽可能的节省花费呢?她发现这并不是一个简单的问题,于是她来向你请教。
找出一条从城市A到B的旅游路线,出发和到达城市中的机场可以任意选取,要求总的花费最少。
输入格式
第一行有4个正整数s,t,A,B。
S(0<S≤100)表示城市的个数,tt表示飞机单位里程的价格,A,B分别为城市A,B的序号,(1≤A,B≤S)。
接下来有S行,其中第I行均有7个正整数xi1,yi1,xi2,yi2,xi3,yi3,Ti,这当中的(xi1,yi1),(xi2,yi2),(xi3,yi3)分别是第ii个城市中任意33个机场的坐标,TiTi为第ii个城市高速铁路单位里程的价格。
输出格式
共1个数据对应测试数据。 保留一位小数。
输入输出样例
输入
3 10 1 3 1 1 1 3 3 1 30 2 5 7 4 5 2 1 8 6 8 8 11 6 3
输出
47.5
本题我们不妨把每个城市的4个机场看做四个点。那样这图就有4×s 个点。
根据题目描述,我们又知道:每一个机场都与另外每一个机场互通,差别只是在是否是同一个城市:
如果是,那么只能走高速铁路;
如果不是,那么只能走航道。用一个判断来计算这条路的花费即可。
最后跑最短路,答案为到达城市的4个机场的花费的最小值。
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <string> 5 #include <math.h> 6 #include <algorithm> 7 #include <vector> 8 #include <stack> 9 #include <queue> 10 #include <set> 11 #include <map> 12 #include <sstream> 13 const int INF=0x3f3f3f3f; 14 typedef long long LL; 15 const int mod=1e9+7; 16 //const double PI=acos(-1); 17 #define Bug cout<<"---------------------"<<endl 18 const int maxn=1e5+10; 19 using namespace std; 20 21 int n,A,B; 22 double cost; 23 24 struct node 25 { 26 int x, y; 27 int city; 28 }; 29 30 node PT[4]; 31 node APT[maxn]; 32 int cntt; 33 34 struct Edge_node 35 { 36 int to; 37 int next; 38 double cost; 39 }Edge[7005<<1]; 40 41 int head[3000]; 42 int cnt; 43 double dis[3000]; 44 int ctcost[maxn]; 45 46 struct cmp1 47 { 48 bool operator()(int x,int y) 49 { 50 return dis[x]>dis[y]; 51 } 52 }; 53 54 void add_edge(int u,int v,double val) 55 { 56 Edge[cnt].to=v; 57 Edge[cnt].cost=val; 58 Edge[cnt].next=head[u]; 59 head[u]=cnt++; 60 } 61 62 double juli(int x1, int y1, int x2, int y2) 63 { 64 return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); 65 } 66 67 void Dijkstra() 68 { 69 fill(dis+1,dis+1+cntt,INF); 70 priority_queue<int,vector<int>,cmp1 > qe; 71 for(int i=A*4-3;i<=A*4;i++) 72 { 73 dis[i]=0; 74 qe.push(i); 75 } 76 while(!qe.empty()) 77 { 78 int u=qe.top(); 79 qe.pop(); 80 for(int i=head[u];i!=-1;i=Edge[i].next) 81 { 82 int v=Edge[i].to; 83 if(dis[u]+Edge[i].cost<dis[v]) 84 { 85 dis[v]=dis[u]+Edge[i].cost; 86 qe.push(v); 87 } 88 } 89 } 90 } 91 92 int main() 93 { 94 cnt=cntt=0; 95 memset(head,-1,sizeof(head)); 96 scanf("%d %lf %d %d",&n,&cost,&A,&B); 97 for(int i=1;i<=n;i++) 98 { 99 scanf("%d %d %d %d %d %d %d",&PT[0].x,&PT[0].y,&PT[1].x,&PT[1].y,&PT[2].x,&PT[2].y,&ctcost[i]); 100 while((PT[0].x-PT[1].x)*(PT[2].x-PT[1].x)!=(PT[0].y-PT[1].y)*(PT[1].y-PT[2].y)) 101 { 102 node t=PT[0]; 103 PT[0]=PT[1];PT[1]=PT[2];PT[2]=t; 104 } 105 PT[3].x=PT[2].x+(PT[0].x-PT[1].x);//求出最后一个点 106 PT[3].y=PT[2].y+(PT[0].y-PT[1].y); 107 for(int k=0;k<4;k++) 108 { 109 PT[k].city=i; 110 APT[++cntt]=PT[k]; 111 } 112 } 113 for(int i=1;i<=cntt;i++)//计算每两个点之间的费用 114 { 115 for(int j=i+1;j<=cntt;j++) 116 { 117 double val; 118 if(APT[i].city==APT[j].city) 119 val=juli(APT[i].x,APT[i].y,APT[j].x,APT[j].y)*ctcost[APT[i].city]; 120 else val=juli(APT[i].x,APT[i].y,APT[j].x,APT[j].y)*cost; 121 add_edge(i,j,val); 122 add_edge(j,i,val); 123 } 124 } 125 Dijkstra();//我竟然忘写这个了。。。 126 double ans=INF; 127 for(int i=B*4-3;i<=B*4;i++) 128 { 129 if(ans>dis[i]) 130 ans=dis[i]; 131 } 132 printf("%.1f ",ans); 133 return 0; 134 }