zoukankan      html  css  js  c++  java
  • POJ 2502 最短路

    题意略。

    思路:

    本题有必要记录一下。首先是dijkstra求最短路没问题,关键是在建图的时候,地铁沿线还要加上行走互达的边,因为:

                                                                                       

    在本图中,AC之间的最短时间有可能不是A->B->C这么走,而是有可能从A走到C,这个地方没有考虑周全,wa了几发。

    代码如下:

    堆优化版:

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstdio>
      4 #include<cstring>
      5 #include<cmath>
      6 #include<vector>
      7 #include<queue>
      8 using namespace std;
      9 const int maxn = 255;
     10 const int INF = 0x3f3f3f3f;
     11 const double eps = 1e-6;
     12 
     13 struct edge{
     14     int to;
     15     double cost;
     16     edge(int to = 0,double cost = 0){
     17         this->to = to,this->cost = cost;
     18     }
     19 };
     20 struct Point{
     21     double x,y;
     22     Point(double x = 0,double y = 0){
     23         this->x = x,this->y = y;
     24     }
     25 };
     26 struct node{
     27     int v;
     28     double c;
     29     node(int v = 0,double c = 0){
     30         this->v = v,this->c = c;
     31     }
     32 };
     33 struct cmp{
     34     bool operator() (const node& n1,const node& n2){
     35         return n1.c > n2.c;
     36     }
     37 };
     38 
     39 bool vis[maxn];
     40 double dist[maxn];
     41 vector<edge> graph[maxn];
     42 priority_queue<node,vector<node>,cmp> que;
     43 Point st,ed,store[maxn];
     44 int tail = 0;
     45 
     46 double calDist(Point p1,Point p2,bool signal){
     47     double dx = p1.x - p2.x;
     48     double dy = p1.y - p2.y;
     49     double len = sqrt(dx * dx + dy * dy);
     50     len /= 1000.0;
     51     double denominator = signal ? 40.0 : 10.0;
     52     double ret = len / denominator;
     53     ret *= 60.0;
     54     return ret;
     55 }
     56 int sgn(double x){
     57     if(fabs(x) < eps) return 0;
     58     else if(x > 0) return 1;
     59     return -1;
     60 }
     61 int dijkstra(){
     62     while(que.size()) que.pop();
     63     for(int i = 0;i < tail;++i) dist[i] = INF;
     64     memset(vis,false,sizeof(vis));
     65     dist[0] = 0;
     66     int idx = tail - 1;
     67     que.push(node(0,0));
     68     while(que.size()){
     69         node temp = que.top();
     70         que.pop();
     71         int v = temp.v;
     72         if(vis[v]) continue;
     73         vis[v] = true;
     74         for(int i = 0;i < graph[v].size();++i){
     75             edge e = graph[v][i];
     76             int to = e.to;
     77             double cost = e.cost;
     78             if(vis[to] || sgn(dist[to] - cost - dist[v]) <= 0) continue;
     79             dist[to] = cost + dist[v];
     80             que.push(node(to,dist[to]));
     81         }
     82     }
     83     int ret = int(dist[idx] + 0.5);
     84     return ret;
     85 }
     86 bool Read(){
     87     double x,y;
     88     bool jud = (scanf("%lf%lf",&x,&y) == 2);
     89     if(!jud) return false;
     90     store[tail++] = Point(x,y);
     91     while(scanf("%lf%lf",&x,&y) == 2 && sgn(x + 1) != 0){
     92         store[tail++] = Point(x,y);
     93     }
     94     return true;
     95 }
     96 void add_e(int from,int to,bool signal){
     97     double cost = calDist(store[from],store[to],signal);
     98     graph[from].push_back(edge(to,cost));
     99     graph[to].push_back(edge(from,cost));
    100 }
    101 
    102 int main(){
    103     scanf("%lf%lf%lf%lf",&st.x,&st.y,&ed.x,&ed.y);
    104     store[tail++] = st;
    105     int keep = tail;
    106     while(Read()){
    107         for(int i = keep;i < tail - 1;++i){
    108             add_e(i,i + 1,true);
    109         }
    110         for(int i = keep;i < tail;++i)
    111             for(int j = 0;j < i;++j)
    112                 add_e(i,j,false);
    113         keep = tail;
    114     }
    115     store[tail++] = ed;
    116     int idx = tail - 1;
    117     for(int i = 0;i < idx;++i) add_e(idx,i,false);
    118     int ans = dijkstra();
    119     printf("%d
    ",ans);
    120     return 0;
    121 }

    普通Dijkstra:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<cmath>
    using namespace std;
    const int maxn = 255;
    const double v1 = 10000;
    const double v2 = 40000;
    const double INF = 0x3f3f3f3f;
    const double eps = 1e-6;
    
    struct edge{
        int to;
        double cost;
        edge(int to,double cost = 0){
            this->to = to,this->cost = cost;
        }
    };
    struct Point{
        double x,y;
        Point(double x = 0,double y = 0){
            this->x = x,this->y = y;
        }
    };
    
    Point store[maxn],st,ed;
    vector<edge> graph[maxn];
    double dist[maxn];
    bool vis[maxn];
    int tail = 0;
    
    int sgn(double x){
        if(fabs(x) < eps) return 0;
        else if(x > 0) return 1;
        return -1;
    }
    double calDist(Point p1,Point p2){
        double dx = p1.x - p2.x;
        double dy = p1.y - p2.y;
        return sqrt(dx * dx + dy * dy);
    }
    void add_e(int from,int to,double cost){
        graph[from].push_back(edge(to,cost));
        graph[to].push_back(edge(from,cost));
    }
    int Dijkstra(){
        for(int i = 0;i < tail;++i){
            vis[i] = false;
            dist[i] = INF;
        }
        int cnt = tail;
        dist[0] = 0;
        while(cnt > 0){
            int idx = -1;
            for(int i = 0;i < tail;++i){
                if(vis[i]) continue;
                if(idx == -1 || sgn(dist[idx] - dist[i]) > 0) idx = i;
            }
            vis[idx] = true;
            --cnt;
            for(int i = 0;i < graph[idx].size();++i){
                edge e = graph[idx][i];
                int to = e.to;
                double cost = e.cost;
                if(vis[to] || sgn(dist[to] - dist[idx] - cost) <= 0) continue;
                dist[to] = dist[idx] + cost;
            }
        }
        int ret = int(dist[tail - 1] + 0.5);
        return ret;
    }
    bool Read(){
        double x,y;
        bool jud = (scanf("%lf%lf",&x,&y) == 2);
        if(!jud) return false;
        store[tail++] = Point(x,y);
        while(scanf("%lf%lf",&x,&y) == 2 && sgn(x + 1) != 0){
            store[tail++] = Point(x,y);
        }
        return true;
    } 
    
    int main(){
        scanf("%lf%lf%lf%lf",&st.x,&st.y,&ed.x,&ed.y);
        tail = 0;
        store[tail++] = st;
        int keep = tail;
        while(Read()){
            for(int i = keep;i < tail - 1;++i){
                double c = calDist(store[i],store[i + 1]) / v2 * 60.0;
                add_e(i,i + 1,c);
            }
            for(int i = keep;i < tail;++i){
                for(int j = 0;j < i;++j){
                    double c = calDist(store[i],store[j]) / v1 * 60.0;
                    add_e(i,j,c);
                }
            }
            keep = tail;
        }
        store[tail++] = ed;
        int idx = tail - 1;
        for(int i = 0;i < idx;++i){
            double c = calDist(store[idx],store[i]) / v1 * 60.0;
            add_e(idx,i,c);
        }
        int ans = Dijkstra();
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    查询存储过程 视图调用关系
    正在执行的sql
    [BAT] BAT 顺序执行其他BAT 批处理文件可设置时间间隔(实际场景Windows下依次启动多个Tomcat服务)
    QT 实用代码片段 (持续更新)
    C# 阻塞队列 BlockingQueue<T>
    [Windows] IE版本历史
    [Windows] Windows操作系统的历史
    [C#] 使用表驱动法替代IF Else 和 Switch Case
    Bat实现IP设置切换(公司IP和家里的IP)
    Sublime Text 2 常用快捷键
  • 原文地址:https://www.cnblogs.com/tiberius/p/11379153.html
Copyright © 2011-2022 走看看