POJ - 2502(最短路dijkstra+链式前向星)

版权声明:本文为博主原创文章,转载请附上源地址。 https://blog.csdn.net/Ema1997/article/details/79542996

反思:
1.地铁可能会拐很大的弯,所以要注意同一条地铁上的不相邻点之间的时间也需要更新,更新的时候按照走路的时间算。
2.由1知,以后一定要看所存图是否把所有边全都已经存储进去了,不能落边。
3.由于是完全图,考虑到SPFA遍历所有边的方法可能会TLE,就直接用了dijkstra来遍历点,求得所要点后直接返回。
4.边的个数要判断对,边数最多为 点数点数(如果不存储到自己的边的话,则最多为(点数-1) 点数)
AC代码(非链式前向星)

#include <iostream>
#include <queue>
#include <cstdio>
#include <map>
#include <cstring>
#include <stack>
#include <string>
#include <vector>
#include <cmath>

using namespace std;

const int INF = 0x3f3f3f3f;
const int maxn = 210;
const int maxm = 25000;

struct Node
{
    int x, y;
    Node(){}
    Node(int xx, int yy) : x(xx), y(yy) {}
};

struct Edge
{
    int v, w;
    Edge(int vv, int ww): v(vv), w(ww) {}
    Edge() {}
    bool operator < (Edge e) const
    {
        return w > e.w;
    }
};

int n;
Node node[maxn];
int vis[maxn];
int color[maxn];
double dis[maxn];
double cost[maxn][maxn];

void Init()
{
    n = 2;//至少为2个,1是原点,2是终点
    memset (color, 0, sizeof(color));
    memset (vis, 0, sizeof(vis));
    for (int i = 1; i < maxn; i++) {
        for (int j = 1; j < maxn; j++) {
            if (i == j) {
                cost[i][j] = 0;
            } else {
                cost[i][j] = INF;
            }
        }
        dis[i] = INF;
    }
}

inline double round( double d )
{
    return floor( d + 0.5 );
}

double Distance(Node a, Node b)
{
    double x = (double)(a.x - b.x);
    double y = (double)(a.y - b.y);
    return sqrt(x * x + y * y);
}

double Dijkstra()
{

    //printf ("%lf\n", dis[2]);
    dis[1] = 0;
    priority_queue<Edge> q;
    q.push(Edge(1, 0));
    while (!q.empty()) {
        Edge tmp = q.top();
        q.pop();
        if (vis[tmp.v]) continue;
        if (tmp.v == 2) break;
        vis[tmp.v] = 1;
        for (int i = 1; i <= n; i++) {
            if (vis[i]) continue;
            double t = cost[tmp.v][i];
            double md = dis[tmp.v] + t;
            if (md < dis[i]) {
                dis[i] = md;
                q.push(Edge(i, md));
            }
        }
    }
    return dis[2];
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    //freopen("out1.txt", "w", stdout);
    #endif // ONLINE_JUDGE
    Init ();
    int flag = 0;
    scanf ("%d%d%d%d", &node[1].x, &node[1].y, &node[2].x, &node[2].y);
    color[2] = 1;
    int x, y;
    while (scanf ("%d%d", &x, &y) != EOF) {
        if (x == -1 && y == -1) {
            flag = 0;
            continue;
        }
        node[++n] = Node(x, y);
        if (flag) {
            color[n] = color[n - 1];
            double t = Distance (node[n - 1], node[n]) * 60.0 / 40000.0;
            cost[n][n - 1] = cost[n - 1][n] = min (cost[n][n - 1], t);
        } else {
            color[n] = color[n - 1] + 1;
            flag = 1;
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j < i; j++) {
            //if (color[i] == color[j]) continue;
            double t = Distance (node[i], node[j]) / 10000.0 * 60;
            cost[i][j] = cost[j][i] = min (cost[i][j], t);
        }
    }
    double d = Dijkstra ();
    /*for (int i = 1; i <= n; i++) {
        printf ("%d %lf\n", i, dis[i]);
    }*/
    printf ("%.0f\n", round (d));
    return 0;
}

链式前向星:

#include <iostream>
#include <queue>
#include <cstdio>
#include <map>
#include <cstring>
#include <stack>
#include <string>
#include <vector>
#include <cmath>

using namespace std;

const int INF = 0x3f3f3f3f;
const int maxn = 210;
const int maxm = 50000;

struct Node
{
    int x, y;
    Node(){}
    Node(int xx, int yy) : x(xx), y(yy) {}
};

struct Edge
{
    int v, next;
    double w;
    Edge(){}
    Edge(int vv, double ww, int nn) {
        v = vv;
        w = ww;
        next = nn;
    }
    bool operator < (Edge e) const
    {
        return w > e.w;
    }
};

int n;
int head[maxn];
Node node[maxn];
Edge e[maxm];
int vis[maxn];
int cnt;
int color[maxn];
double dis[maxn];

void Init()
{
    n = 2;//至少为2个,1是原点,2是终点
    cnt = 0;
    memset (head, -1, sizeof(head));
    memset (color, 0, sizeof(color));
    memset (vis, 0, sizeof(vis));
}

void Add(int u, int v, double w)
{
    e[cnt] = Edge(v, w, head[u]);
    head[u] = cnt++;
}

inline double round( double d )
{
    return floor( d + 0.5 );
}

double Distance(Node a, Node b)
{
    double x = (double)(a.x - b.x);
    double y = (double)(a.y - b.y);
    return sqrt(x * x + y * y);
}

double Dijkstra()
{
    for (int i = 1; i <= n; i++) {
        dis[i] = INF;
    }
    dis[1] = 0;
    priority_queue<Edge> q;
    q.push(Edge(1, 0, -1));
    while (!q.empty()) {
        Edge tmp = q.top();
        q.pop();
        if (vis[tmp.v]) continue;
        if (tmp.v == 2) break;
        vis[tmp.v] = 1;
        for (int i = head[tmp.v]; i != -1; i = e[i].next) {
            Edge t = e[i];
            if (vis[t.v]) continue;
            double md = dis[tmp.v] + t.w;
            if (md < dis[t.v]) {
                dis[t.v] = md;
                q.push(Edge(t.v, md, -1));
            }
        }
    }
    return dis[2];
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    //freopen("out1.txt", "w", stdout);
    #endif // ONLINE_JUDGE
    Init ();
    scanf ("%d%d%d%d", &node[1].x, &node[1].y, &node[2].x, &node[2].y);
    color[1] = 0;
    color[2] = 1;
    color[3] = 3;
    int x, y;
    while (scanf ("%d%d", &x, &y) != EOF) {
        if (x == -1 && y == -1) {
            color[n + 1] = n + 1;
            continue;
        }
        node[++n] = Node(x, y);
        if (n != color[n]) {
            color[n] = color[n - 1];
            double t = Distance (node[n - 1], node[n]) / 40.0 * 60 / 1000;
            Add (n - 1, n, t);
            Add (n, n - 1, t);
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j < i; j++) {
            if (color[i] == color[j] && i == j + 1) continue;
            double t = Distance (node[i], node[j]) / 1000.0 / 10 * 60;
            Add (i, j, t);
            Add (j, i, t);
        }
    }
    printf ("%.0f\n", round (Dijkstra ()));
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Ema1997/article/details/79542996