Subway (using priority queues dijkstar)

Subway (using priority queues dijkstar)

topic

poj 2502 Subway

Subject to the effect

Given the starting point and end point, the middle of several subway lines, you can choose to walk or take the subway, shortest time spent.

Thinking

The most important thing is to build map. I used here is the adjacency list (vector arrays to achieve, so that even if there is heavy side does not matter). Virtually all points are within walking distance, it just takes more time.

note

Tag can not be used when using the adjacency list used because of the heavy side.

Code

#include <algorithm>
#include <iostream>
#include <vector>
#include <memory.h>
#include <queue>
#include <cmath>
#define maxn 206
#define INF 0x3f3f3f
using namespace std;

struct node
{
        double x, y;
        node(double xx, double yy) { x = xx, y = yy; }
        node() {}
} es[maxn];
int len = 0;
double d[maxn];
int inq[maxn];
vector<pair<int, double>> eg[maxn];
typedef pair<double, int> p;
void init()
{
        for (int i = 1; i <= maxn; i++)
                inq[i] = 0;
        for (int i = 1; i <= maxn; i++)
                eg[i].clear();
        for (int i = 1; i <= maxn; i++)
                d[i] = INF;
}
double getdic(double x1, double y1, double x2, double y2)
{
        return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

void dijkstar()
{
        priority_queue<p, vector<p>, greater<p>> q;
        d[1] = 0;
        q.push(p(d[1], 1));//将起点推入队列
        

        while (!q.empty())
        {

                p cur = q.top();//取出最近的节点
                int now = cur.second;//该节点的id
                inq[now]=0;//取消标记
                q.pop();

                for (int i = 0; i < eg[now].size(); i++)//遍历所有该节点链接的点
                {
                        int v = eg[now][i].first;
                        if (d[v] > eg[now][i].second + d[now])
                        {
                                d[v] = eg[now][i].second + d[now];
                                if (inq[v])//添加标记,优化
                                        continue;
                                inq[v] = 1;

                                q.push(p(d[v], v));
                        }
                }
        }
}

int main()
{
        init();
        double x, y;
        cin >> x >> y;
        es[++len] = node(x, y);
        cin >> x >> y;
        es[++len] = node(x, y);
        int last = 2;
        while (cin >> x >> y) //地铁的路线
        {
                if (x == -1.0)
                {
                        for (int i = last + 1; i < len; i++)
                        {
                                double dis = getdic(es[i].x, es[i].y, es[i + 1].x, es[i + 1].y) / 40000.0;
                                eg[i].push_back(make_pair(i + 1, dis));
                                eg[i + 1].push_back(make_pair(i, dis));
                        }
                        last = len;
                        continue;
                }
                es[++len] = node(x, y);
        }

        for (int i = 1; i <= len; i++)//补全所有可以步行的边
                for (int j = i + 1; j <= len; j++)
                {
                        double dis = getdic(es[i].x, es[i].y, es[j].x, es[j].y) / 10000.0;
                        eg[i].push_back(make_pair(j, dis));
                        eg[j].push_back(make_pair(i, dis));
                }

        dijkstar();
        cout << int(d[2] * 60 + 0.5) << endl;
}

Guess you like

Origin www.cnblogs.com/tttfu/p/11233044.html