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\n",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\n",ans);
    return 0;
}

 

posted @ 2019-08-19 19:31  温和的提比略  阅读(110)  评论(0编辑  收藏  举报