zoukankan      html  css  js  c++  java
  • 【NOIP2001】【Luogu1027】Car的旅行路线

    problem

    solution

    codes

    //1.计算几何求第四点坐标, 方法很多
    //2.虚点,到A城市的四个机场边权都为0
    //3.SPFA跑最短路
    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<cstdio>
    #include<vector>
    #include<queue>
    using namespace std;
    
    //Timu
    double n, m, a, b;
    double x[500], y[500], t[110];
    
    //Graph
    struct Edge{
        int to;  double w;
        Edge(int x, double y):to(x),w(y){}
    };
    vector<Edge>G[500];
    void insert(int u,int v,double w){
        G[u].push_back(Edge(v,w));
    }
    double distant(double nx,double ny,double mx,double my){
        return sqrt((nx-mx)*(nx-mx)+(ny-my)*(ny-my));
    }
    
    //spfa
    queue<int>q;
    int vis[500];
    double dis[500];
    void spfa(){
        while(!q.empty()){
            int u = q.front();  q.pop();  vis[u] = 0;
            for(int i = 0; i < G[u].size(); i++){
                int v = G[u][i].to;
                if(dis[u]+G[u][i].w<dis[v]){
                    dis[v] = dis[u]+G[u][i].w;
                    if(!vis[v]){
                        q.push(v);
                        vis[v] = 1;
                    }
                }
            }
        }
    }
    
    int main(){
        int T;  cin>>T;
        while(T--){
            //1.初始化
            memset(x,0,sizeof x);
            memset(y,0,sizeof y);
            memset(t,0,sizeof t);
            memset(vis,0,sizeof vis);
            //2.datein
            cin>>n>>m>>a>>b;
            for(int i = 0; i < n; i++){
                for(int j = 1; j < 4; j++)
                    cin>>x[i*4+j]>>y[i*4+j];
                cin>>t[i+1];
                //point4, 
                double l1=distant(x[i*4+1],y[i*4+1],x[i*4+2],y[i*4+2]);
                double l2=distant(x[i*4+1],y[i*4+1],x[i*4+3],y[i*4+3]);
                double l3=distant(x[i*4+2],y[i*4+2],x[i*4+3],y[i*4+3]);
                double l=max(l1,max(l2,l3));//三条里最常的就是对角线,然后中点坐标得到第4点
                if(l1 == l)x[i*4+4]=(x[i*4+1]+x[i*4+2])-x[i*4+3], y[i*4+4]=(y[i*4+1]+y[i*4+2])-y[i*4+3];
                if(l2 == l)x[i*4+4]=(x[i*4+1]+x[i*4+3])-x[i*4+2], y[i*4+4]=(y[i*4+1]+y[i*4+3])-y[i*4+2];
                if(l3 == l)x[i*4+4]=(x[i*4+2]+x[i*4+3])-x[i*4+1], y[i*4+4]=(y[i*4+2]+y[i*4+3])-y[i*4+1];
            }
            //3.预处理,建图(把所有机场连起来就好啦啦啦~)
            n *= 4;
            for(int i = 1; i <= n; i++){
                for(int j = 1; j <= n; j++){
                    if(i == j)continue;
                    int c1 = (i-1)/4+1, c2 = (j-1)/4+1;
                    if(c1 == c2){
                        double w = distant(x[i],y[i],x[j],y[j])*t[c1];
                        insert(i,j,w);
                        insert(j,i,w);
                    }else{
                        double w = distant(x[i],y[i],x[j],y[j])*m;
                        insert(i,j,w);
                        insert(j,i,w);
                    }
                }
            }
            //4.run
            for(int i = 1; i <= n; i++)dis[i] = 1e9+1;
            for(int i = (a-1)*4+1; i <= a*4; i++){
                q.push(i);
                dis[i] = 0;
                vis[i] = 1;
            }
            spfa();
            //5.dateout
            double ans = 1e9;
            for(int i = (b-1)*4+1; i <= 4*b; i++)ans = min(ans, dis[i]);
            printf("%.1lf
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    C# 面向对象之概念理解(2)
    Linux中常用常用常用快捷键
    shell基本脚本命令
    awk命令详解及应用技巧
    Windows(64位IIS)未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序
    基础知识(net)<3> virtural , new ,override
    WCF REST<2>: 消费WCF REST 服务
    智能表单(2):简单使用HtmlEditor
    智能表单(1) : 开源HtmlEditor介绍
    ASP.NET Web API <2> 跨域消费Web API(JSONP)
  • 原文地址:https://www.cnblogs.com/gwj1314/p/9444819.html
Copyright © 2011-2022 走看看