• AC日记——Car的旅行路线 洛谷 P1027


    Car的旅行路线

    思路:

      这题不难,就是有点恶心;

      而且,请认真读题目(就是题目卡死劳资);

    来,上代码:

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    #define maxn 807
    #define maxm 860005
    #define INF 0x7fffffff
    
    struct CityType {
        double x[4],y[4],c;
    };
    struct CityType city[maxn];
    
    int T,n,s,t,head[maxn],E[maxm],V[maxm];
    int cnt,que[maxn<<2];
    
    double W[maxm],dis[maxn],c;
    
    bool if_[maxn];
    
    inline double d(int now,int v1,int v2)
    {
        double x1=city[now].x[v1],x2=city[now].x[v2];
        double y1=city[now].y[v1],y2=city[now].y[v2];
        return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
    }
    
    inline void edge_add(int u,int v,double w)
    {
        E[++cnt]=head[u],V[cnt]=v,W[cnt]=w,head[u]=cnt;
        E[++cnt]=head[v],V[cnt]=u,W[cnt]=w,head[v]=cnt;
    }
    
    double ds(int u,int v1,int v,int v2)
    {
        double xx=city[u].x[v1]-city[v].x[v2];
        double yy=city[u].y[v1]-city[v].y[v2];
        return sqrt(xx*xx+yy*yy);
    }
    
    void spfa()
    {
        memset(if_,false,sizeof(if_));
        memset(dis,0x7f,sizeof(dis));
        int h=0,tail=4;que[0]=s*4-3,que[1]=s*4-2;
        que[2]=s*4-1,que[3]=s*4,if_[s*4-3]=true;
        if_[s*4-2]=true,if_[s*4-1]=true,if_[s*4]=true;
        dis[s*4-3]=0,dis[s*4-2]=0,dis[s*4-1]=0,dis[s*4]=0;
        while(h<tail)
        {
            int now=que[h++];if_[now]=false;
            for(int i=head[now];i;i=E[i])
            {
                if(dis[V[i]]>dis[now]+W[i])
                {
                    dis[V[i]]=dis[now]+W[i];
                    if(!if_[V[i]]) if_[V[i]]=true,que[tail++]=V[i];
                }
            }
        }
    }
    
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            memset(head,0,sizeof(head)),cnt=0;
            scanf("%d%lf%d%d",&n,&c,&s,&t);
            for(int i=1;i<=n;i++)
            {
                for(int v=0;v<3;v++) scanf("%lf%lf",&city[i].x[v],&city[i].y[v]);
                scanf("%lf",&city[i].c);
                double d01=d(i,0,1),d02=d(i,0,2),d12=d(i,1,2);
                int pos=i*4-3;
                if(d01+d02==d12)
                {
                    city[i].x[3]=city[i].x[1]+city[i].x[2]-city[i].x[0];
                    city[i].y[3]=city[i].y[1]+city[i].y[2]-city[i].y[0];
                }
                else if(d01+d12==d02)
                {
                    city[i].x[3]=city[i].x[0]+city[i].x[2]-city[i].x[1];
                    city[i].y[3]=city[i].y[0]+city[i].y[2]-city[i].y[1];
                }
                else
                {
                    city[i].x[3]=city[i].x[0]+city[i].x[1]-city[i].x[2];
                    city[i].y[3]=city[i].y[0]+city[i].y[1]-city[i].y[2];
                }
                for(int j=0;j<=3;j++)
                {
                    for(int v=j+1;v<=3;v++) edge_add(pos+j,pos+v,sqrt(d(i,j,v))*city[i].c);
                }
            }
            for(int i=1;i<=n;i++)
            {
                for(int j=i+1;j<=n;j++)
                {
                    int posi=i*4-3,posj=j*4-3;
                    for(int v=0;v<4;v++)
                    {
                        for(int z=0;z<4;z++) edge_add(v+posi,z+posj,ds(i,v,j,z)*c);
                    }
                }
            }
            spfa();double ans=INF;
            for(int i=0;i<=3;i++) ans=min(ans,dis[i+t*4-3]);
            printf("%.1lf",ans);
        }
        return 0;
    }
  • 相关阅读:
    Ubuntu下录音机程序的使用
    Bash中的数学计算
    Bash中的数学扩展
    Bash的命令替换
    top的用法
    VirtualBox的快照功能
    格式化输出和printf命令
    read命令读取用户输入
    Bash的作业控制
    Codeforces Round #455 (Div. 2)
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6758511.html
Copyright © 2020-2023  润新知