题目描述
Caesar远征高卢回来后,对你大加赞赏,他亲自来到Genoa视察。
Genoa在你的建设下变得无比繁荣,由于财政收入的增加,你为城市修建了交通系统。古罗马的交通系统由两部分组成——Dirt Road和Rome Road。两个路口间只可能是其中一种道路。在Rome Road上可以驾驶马车,而在Dirt Road上则不行。由于修建道路是一项浩大的工程,使得你无法将整个城市用Rome Road连接起来。
现在Caesar已经到达码头,他要求去你家参观。Caesar由一个癖好,喜欢坐车而不喜欢走路。所以Caesar走Dirt Road时的不满值要比走Rome Road时大。
为了不让Caesar过于不满而罢免你的职位,请设计路线使得Caesar的不满值最小。
输入格式
输入数据第一行有两个实数,分别表示走Dirt Road和Rome Road一个单位长度时Caesar的不满值。接下来是一个整数N(N<=1000),代表路口总数。接下来有N行,每行一组实数(x,y)分别描述这N个路口的坐标。接下来有若干行,每行一组整数(i,j),表示第i个路口与第j个路口间为Rome Road,以0 0结束。最后两行,每行一对实数,分别描述码头和你家的坐标。
输出格式
输出Caesar从码头到你家的最小不满值,保留4位小数
输入输出样例
输入 #1
100.0 2.0
2
1.0 0.0
2.0 1.0
1 2
0 0
0.0 0.0
2.0 2.0
输出 #1
202.8284
#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<queue>
#include<cmath>
using namespace std;
const int MAXN = 1004;
const int INF = 100000000;
double graph[MAXN][MAXN]; //邻接矩阵存图
double dis[MAXN];
bool vis[MAXN];
double cx[MAXN]; //cx[i]存放i号路口的x坐标
double cy[MAXN]; //cx[i]存放i号路口的y坐标
void Dijkstra(int s,int n){
fill(dis,dis+n+2,INF);
dis[s] = 0;
for(int i=0;i<=n+1;i++){
int u = -1;
int minDis = INF;
for(int j=0;j<=n+1;j++){
if(!vis[j] && dis[j] < minDis){
minDis = dis[j];
u = j;
}
}
if(u == n+1){
break;
}
vis[u] = true;
for(int j=0;j<=n+1;j++){
double w = graph[u][j];
if(!vis[j]){
if(dis[j] > dis[u] + w){
dis[j] = dis[u] + w;
}
}
}
}
}
int main(){
double dirt,rome; //dirt路的不满度和rome路的不满度
int n; //路口个数
double x,y,sx,sy,tx,ty,height,width; //坐标
int u,v; //边的起点和终点
double w; //边的权重
cin>>dirt>>rome;
cin>>n;
//输入每个路口的坐标
for(int i=1;i<=n;i++){
cin>>cx[i]>>cy[i];
}
//输入路口u与路口v之间的Rome Road边
while(cin>>u>>v){
if(u==0 && v==0){break;}
height = cy[u] - cy[v]; //垂直长度
width = cx[u] - cx[v]; //水平长度
//计算边的权重
w = sqrt(height*height + width*width) * rome;
graph[u][v] = graph[v][u] = w;
}
cin>>cx[0]>>cy[0]>>cx[n+1]>>cy[n+1];
/*
** 任意两点之间用dirt路连接上
** 如果i和j之间本来没有路,那就直接用dirt road
** 如果i和j之间本来有rome raod,那就比较一下dirt road和rome road的不满度,
** 选小的那个
*/
for(int i=0;i<=n+1;i++){
for(int j=i+1;j<=n+1;j++){
height = cy[i] - cy[j];
width = cx[i] - cx[j];
w = sqrt(height*height + width*width) * dirt;
if(graph[i][j] == 0 || graph[i][j] > w){
graph[i][j] = graph[j][i] = w;
}
}
}
Dijkstra(0,n);
cout<<fixed<<setprecision(4)<<dis[n+1]<<endl;
return 0;
}