反思:
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;
}