P1027 [NOIP2001 提高组] Car 的旅行路线
作者:互联网
P1027 [NOIP2001 提高组] Car 的旅行路线(计算几何 + Floyed最短路)
大致解题思路:
1、每个城市有四个点,N 个城市有4N个点,我们对这4N个点进行floyed,这就是我们最终的结果
2、根据三个点判断出第四个点的坐标:
3、通过坐标求距离:
4、因为每个点到其他点的旅行方式不一样,所以我们分情况判断花费,也可以说是dp数组的初始化:
5、对每个点进行floyed:
说一个当时写的时候犯的错误吧,是从A城市到达B城市,不是从序号A到序号B的城市,当时找了好长时间,后来重新读题才发现的这个问题。wtcl。。
详细解释如下:
1、每个城市有四个点,N 个城市有4N个点,我们对这4N个点进行floyed,这就是我们最终的结果
2、根据三个点判断出第四个点的坐标:
千万注意斜率不为零的情况分开讨论!!0不能做除数
void add(int cnt){
int x1,x2,x3,y1,y2,y3;
x1 = city[cnt-2].x;
x2 = city[cnt-1].x;
x3 = city[cnt].x;
y1 = city[cnt-2].y;
y2 = city[cnt-1].y;
y3 = city[cnt].y;
int k;
int cx,cy;
for(int i=1;i<=3;i++){
if(i==1){
if(x1==x2 && y1==y3){
cx = x3-x1;
city[++cnt].x = x2+cx;
city[cnt].y = y2;
city[cnt].num = city[cnt-1].num;
return ;
}
else if(x1==x3 && y1==y2){
cx = x2-x1;
city[++cnt].x = x3+cx;
city[cnt].y = y3;
city[cnt].num = city[cnt-1].num;
return ;
}
else if(x1==x2 || x1==x3) continue;
k = ((y2-y1)*(y3-y1))/((x2-x1)*(x3-x1));
if(k==-1){
cx = x1-x2;
cy = y1-y2;
city[++cnt].x = x3-cx;
city[cnt].y = y3-cy;
city[cnt].num = city[cnt-1].num;
return ;
}
}
else if(i==2){
if(x2==x1 && y2==y3){
cx = x3-x2;
city[++cnt].x = x2+cx;
city[cnt].y = y1;
city[cnt].num = city[cnt-1].num;
return ;
}
else if(x2==x3 && y2==y1){
cx = x1-x2;
city[++cnt].x = x2+cx;
city[cnt].y = y3;
city[cnt].num = city[cnt-1].num;
return ;
}
else if(x2==x1||x2==x3) continue;
k = ((y1-y2)*(y3-y2))/((x1-x2)*(x3-x2));
if(k==-1){
cx = x2-x1;
cy = y2-y1;
city[++cnt].x = x3-cx;
city[cnt].y = y3-cy;
city[cnt].num = city[cnt-1].num;
return ;
}
}
else if(i==3){
if(x3==x1 && y3==y2){
cx = x2-x3;
city[++cnt].x = x1+cx;
city[cnt].y = y1;
city[cnt].num = city[cnt-1].num;
return ;
}
else if(x3==x2 && y3==y1){
cx = x1-x3;
city[++cnt].x = x2+cx;
city[cnt].y = y2;
city[cnt].num = city[cnt-1].num;
return ;
}
else if(x3==x1 || x3==x2) continue;
k = ((y1-y3)*(y2-y3))/((x1-x3)*(x2-x3));
if(k==-1){
cx = x3-x1;
cy = y3-y1;
city[++cnt].x = x2-cx;
city[cnt].y = y2-cy;
city[cnt].num = city[cnt-1].num;
return ;
}
}
}
}
3、通过坐标求距离:
double dis(int a,int b){
int x1 = city[a].x;
int x2 = city[b].x;
int y1 = city[a].y;
int y2 = city[b].y;
double ans = 0;
ans = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
return ans;
}
4、因为每个点到其他点的旅行方式不一样,所以我们分情况判断花费,也可以说是dp数组的初始化:
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j) dp[i][j] = 0;
else{
if(city[i].num == city[j].num){
dp[i][j] = dist[i][j] * sub[city[i].num];
}
else dp[i][j] = dist[i][j] * t;
}
}
}
5、对每个点进行floyed:
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
dp[i][j] = min(dp[i][j],dp[i][k]+dp[k][j]);
}
}
}
说一个当时写的时候犯的错误吧,是从A城市到达B城市,不是从序号A到序号B的城市,当时找了好长时间,后来重新读题才发现的这个问题。wtcl。。
double ans = 0x7f7f7f7f;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(city[i].num==a&&city[j].num==b){
ans = min(ans,dp[i][j]);
}
}
}
完整代码如下:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdio>
using namespace std;
const int maxn = 4010;
struct infor{//存放各个城市四个点的位置信息
int x,y;
int num;
}city[maxn];
int sub[maxn];//不同城市的地铁价格
int map[maxn][maxn];//当时为了找错误定义的数组,看看是不是构成了矩形
double dp[maxn][maxn];
double dist[maxn][maxn];//各个点之间的距离
void add(int cnt){//找第四个点的位置!!
int x1,x2,x3,y1,y2,y3;
x1 = city[cnt-2].x;
x2 = city[cnt-1].x;
x3 = city[cnt].x;
y1 = city[cnt-2].y;
y2 = city[cnt-1].y;
y3 = city[cnt].y;
int k;
int cx,cy;
for(int i=1;i<=3;i++){
if(i==1){
if(x1==x2 && y1==y3){
cx = x3-x1;
city[++cnt].x = x2+cx;
city[cnt].y = y2;
city[cnt].num = city[cnt-1].num;
return ;
}
else if(x1==x3 && y1==y2){
cx = x2-x1;
city[++cnt].x = x3+cx;
city[cnt].y = y3;
city[cnt].num = city[cnt-1].num;
return ;
}
else if(x1==x2 || x1==x3) continue;
k = ((y2-y1)*(y3-y1))/((x2-x1)*(x3-x1));
if(k==-1){
cx = x1-x2;
cy = y1-y2;
city[++cnt].x = x3-cx;
city[cnt].y = y3-cy;
city[cnt].num = city[cnt-1].num;
return ;
}
}
else if(i==2){
if(x2==x1 && y2==y3){
cx = x3-x2;
city[++cnt].x = x2+cx;
city[cnt].y = y1;
city[cnt].num = city[cnt-1].num;
return ;
}
else if(x2==x3 && y2==y1){
cx = x1-x2;
city[++cnt].x = x2+cx;
city[cnt].y = y3;
city[cnt].num = city[cnt-1].num;
return ;
}
else if(x2==x1||x2==x3) continue;
k = ((y1-y2)*(y3-y2))/((x1-x2)*(x3-x2));
if(k==-1){
cx = x2-x1;
cy = y2-y1;
city[++cnt].x = x3-cx;
city[cnt].y = y3-cy;
city[cnt].num = city[cnt-1].num;
return ;
}
}
else if(i==3){
if(x3==x1 && y3==y2){
cx = x2-x3;
city[++cnt].x = x1+cx;
city[cnt].y = y1;
city[cnt].num = city[cnt-1].num;
return ;
}
else if(x3==x2 && y3==y1){
cx = x1-x3;
city[++cnt].x = x2+cx;
city[cnt].y = y2;
city[cnt].num = city[cnt-1].num;
return ;
}
else if(x3==x1 || x3==x2) continue;
k = ((y1-y3)*(y2-y3))/((x1-x3)*(x2-x3));
if(k==-1){
cx = x3-x1;
cy = y3-y1;
city[++cnt].x = x2-cx;
city[cnt].y = y2-cy;
city[cnt].num = city[cnt-1].num;
return ;
}
}
}
}
double dis(int a,int b){
int x1 = city[a].x;
int x2 = city[b].x;
int y1 = city[a].y;
int y2 = city[b].y;
double ans = 0;
ans = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
return ans;
}
double floyed(int n,int t,int a,int b){
n = 4*n;
for(int i=1;i<=4*n;i++){
for(int j=1;j<=4*n;j++){
dist[i][j] = dis(i,j);
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j) dp[i][j] = 0;
else{
if(city[i].num == city[j].num){
dp[i][j] = dist[i][j] * sub[city[i].num];
}
else dp[i][j] = dist[i][j] * t;
}
}
}
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
dp[i][j] = min(dp[i][j],dp[i][k]+dp[k][j]);
}
}
}
double ans = 0x7f7f7f7f;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(city[i].num==a&&city[j].num==b){
ans = min(ans,dp[i][j]);
}
}
}
return ans;
}
int main(){
int T;
cin >> T;
while(T--){
memset(sub,0,sizeof(sub));
int n,t,a,b;
int cnt = 1;
cin >> n >> t >> a >> b;
for(int i=1;i<=n;i++){
cin >> city[cnt].x >> city[cnt].y;
city[cnt++].num = i;
cin >> city[cnt].x >> city[cnt].y;
city[cnt++].num = i;
cin >> city[cnt].x >> city[cnt].y;
city[cnt].num = i;
cin >> sub[i];
add(cnt);
cnt+=2;
}
memset(map,0,sizeof(map));
for(int i=1;i<=cnt;i++){
int x = city[i].x;
int y = city[i].y;
int num = city[i].num;
map[x][y] = num;
}
// for(int i=1;i<=4*n;i++){
// cout << city[i].x << " " << city[i].y << " " << city[i].num << " " << sub[city[i].num]<< endl;
// }
double ans = floyed(n,t,a,b);
printf("%.1lf\n",ans);
}
return 0;
}
标签:city,cnt,num,NOIP2001,int,Car,P1027,x2,x1 来源: https://blog.csdn.net/yingtingqi/article/details/113917887