Car的旅行路线

链接

19:34
我觉得最短路可以啃掉这道题。

20:09

这蛇皮建边我可以吐槽一天!!!!!!!!

21:00

我去,代码半小时,查错一小时

21:05
我,终于,A了
瘫软

进入题解

其实思维不难,就是一道最短路,是个人都看出来了

就是这个建图毒瘤啊

首先是个矩形已知三个点求第四个点(xa+xb-xc,ya+yb-yc)这个旁边大佬给我的公式(a,b是对顶点,c是另一个已知点)

然后四个点之间都是可以建边的,确切点说

所有点之间都可以建边,一共4n个点

所以打消了我add前向星的想法,因为到处哪里都是边,还不如邻接矩阵

可是我懒得写了,于是取消了add,在spfa里开始暴力瞎跑

对于同一个城市的点代价乘以ti,否则乘以T

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
struct node{
    double x,y;
    int id;
}e[1000101];
int fir[1000101],cnt=0,vis[1000101];
double w[1000101];
double dist[1000101];
double dis(double x1,double y1,double x2,double y2){
    return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
}
int n,m,s,ed;
void spfa(int st){
    for(int i=1;i<=4*n;i++)dist[i]=99999999.9,vis[i]=0;
    for(int i=st;i<=st+3;i++)dist[i]=0.0;
    queue<int> q;
    q.push(st);vis[st]=1;
    q.push(st+1); vis[st+1]=1;
    q.push(st+2); vis[st+2]=1;
    q.push(st+3); vis[st+3]=1;
    while(!q.empty()){
        int x=q.front();q.pop();vis[x]=0;
        for(int j=1;j<=4*n;j++){
            if(j==x)continue;
            double lala=dis(e[x].x,e[x].y,e[j].x,e[j].y);
            if(e[x].id==e[j].id)lala*=w[e[x].id];
            else lala*=(double)m;
            //cout<<w[1]<<endl;
            if(dist[x]+lala<dist[j]){
                dist[j]=dist[x]+lala;
                if(vis[j]==0){
                vis[j]=1;
                q.push(j); 
                }
            }
        }
    }
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d%d%d",&n,&m,&s,&ed);
        for(int i=1;i<=n*4;i+=4){
            int x1,x2,x3,y1,y2,y3,x4,y4,tt;
            int xx1,xx2,xx3,yy1,yy2,yy3;
            scanf("%d%d%d%d%d%d%lf",&x1,&y1,&x2,&y2,&x3,&y3,&w[i/4+1]);
            double d12=dis(x1,y1,x2,y2);
            double d22=dis(x2,y2,x3,y3);
            double d32=dis(x1,y1,x3,y3);
            if(d12>=d22&&d12>=d32)xx1=x1,yy1=y1,xx2=x2,yy2=y2,xx3=x3,yy3=y3;
            if(d22>=d12&&d22>=d32)xx1=x2,yy1=y2,xx2=x3,yy2=y3,xx3=x1,yy3=y1;
            if(d32>=d22&&d32>=d12)xx1=x1,yy1=y1,xx2=x3,yy2=y3,xx3=x2,yy3=y2;
            x4=xx1+xx2-xx3;y4=yy1+yy2-yy3;
            e[i].x=x1,e[i].y=y1;e[i+1].x=x2,e[i+1].y=y2;
            e[i+2].x=x3,e[i+2].y=y3;e[i+3].x=x4,e[i+3].y=y4;
            e[i].id=e[i+1].id=e[i+2].id=e[i+3].id=i/4+1;
        }
        spfa(s);
        double ans=99999999.9;
        for(int i=ed*4-3;i<=4*ed;i++)ans=min(ans,dist[i]);
        printf("%.1f",ans);
    }
    return 0;
} 

转载于:https://www.cnblogs.com/lisuier/p/9637472.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值