• Car的旅行路线


    noip的原题,虽然思维量不大但是挺麻烦的。。。

    原题链接:https://www.luogu.org/problemnew/show/P1027

    本题的主要问题就是求每个城市第四个点的坐标。其余三点之间的连线中,一定有一条是对角线,所以不参与构成这条边的点,与第四个点的连线就是另一条对角线。平行四边形对角线相互评分,第四个点的坐标就求出来了。

    然后就是按题意连边,连边之后做spfa即可,dij想必也可。a城市的每个点取到b城市四个点的最短花费,然后再在a城市的四个点中选一个最小值即可。

    另外注意多组数据的清空与精度问题。

    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<cstring>
    #include<iostream> 
    using namespace std;
    const int inf=1000000000.0;
    int t,n,x[505],y[505],cnt;
    int head[505],gm[505];
    void read(int &y)
    {
        y=0;char x=getchar();
        while(x<'0'||x>'9') x=getchar();
        while(x>='0'&&x<='9')
        {
            y=y*10+x-'0';
            x=getchar();
        }
    }
    struct edge
    {
        int u,v; 
        double w;
    }e[400005];
    void add(int u,int v,double w)
    {
        e[++cnt].u=head[u];
        e[cnt].v=v;
        e[cnt].w=w;
        head[u]=cnt;
    }
    double dis[505];
    void spfa(int s)
    {
        queue<int>q;
        for(int i=0;i<(n<<2);i++) dis[i]=inf;
        q.push(s);dis[s]=0;
        while(!q.empty())
        {
            int t=q.front();q.pop();
            for(int i=head[t];i;i=e[i].u)
            {
                int tmp=e[i].v;
                if(dis[tmp]>dis[t]+e[i].w)
                {
                    dis[tmp]=dis[t]+e[i].w;
                    q.push(tmp);
                }
            }
        }
    }
    double cw(int x,int y,int z,int w)
    {
        return sqrt((x-z)*(x-z)+(y-w)*(y-w));
    }
    double min(double x,double y,double z,double w)
    {
        double re=x;
        if(y<re) re=y;
        if(z<re) re=z;
        if(w<re) re=w;
        return re;
    }
    int main()
    {
        read(t);
        while(t--)
        {
            memset(head,0,sizeof(head));cnt=0;
            int a,b,fm;
            read(n);read(fm);read(a);read(b);
            for(int i=0;i<n;i++)
            {
                int j=i*4;
                read(x[j+1]);read(y[j+1]);
                read(x[j+2]);read(y[j+2]);
                read(x[j+3]);read(y[j+3]);read(gm[i]);
                double w1=cw(x[j+1],y[j+1],x[j+2],y[j+2]);
                double w2=cw(x[j+1],y[j+1],x[j+3],y[j+3]);
                double w3=cw(x[j+2],y[j+2],x[j+3],y[j+3]);
                {
                    if(w1>w2&&w1>w3){x[j]=x[j+1]+x[j+2]-x[j+3];y[j]=y[j+1]+y[j+2]-y[j+3];}
                    if(w2>w1&&w2>w3){x[j]=x[j+1]+x[j+3]-x[j+2];y[j]=y[j+1]+y[j+3]-y[j+2];}
                    if(w3>w1&&w3>w2){x[j]=x[j+3]+x[j+2]-x[j+1];y[j]=y[j+3]+y[j+2]-y[j+1];}
                }
            }
            for(int i=0;i<(n<<2);i++)
            {
                for(int j=0;j<(n<<2);j++)
                {
                    if(i==j) continue;
                    double lw=cw(x[i],y[i],x[j],y[j]);
                    if((i>>2)==(j>>2)) add(i,j,gm[i>>2]*lw);
                    else add(i,j,fm*lw);
                }
            }
            a<<=2,b<<=2;
            double s1,s2,s3,s4;
            spfa(a-4);s1=min(dis[b-4],dis[b-3],dis[b-2],dis[b-1]);
            spfa(a-3);s2=min(dis[b-4],dis[b-3],dis[b-2],dis[b-1]);
            spfa(a-2);s3=min(dis[b-4],dis[b-3],dis[b-2],dis[b-1]);
            spfa(a-1);s4=min(dis[b-4],dis[b-3],dis[b-2],dis[b-1]);
            printf("%.1lf
    ",min(s1,s2,s3,s4));
        }
        return 0;
    }
  • 相关阅读:
    UPC12617 卡片
    mcmf的dijkstra板子(来自PHY学长)
    UPC9630 Mad Veterinarian
    UPC8173【 哈希和哈希表】Three Friends
    UPC9655 Plug It In!
    UPC8428 网格VI
    UPC4248【数论】数字迷阵
    UPC4247【数论】普通递归关系
    SPOJ
    hdu 5992 Finding Hotels (kdTree)
  • 原文地址:https://www.cnblogs.com/zeroform/p/8303007.html
Copyright © 2020-2023  润新知