给定N个点以及它们之间的一些双向路径,求出从第N个点到第1个点的最短路径。
纯粹的单源最短路径题目,图的点最多有1000个,而边最多有2000条(题目数据量不对,数据中可能包含多于2000条边的数据),即边数并没有点数的平方那么多,因此应该考虑使用邻接表存储图,然后采用SPFA或者堆优化的DIJKSTRA求解。
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1005;
const int E = 20005;
const int MAX = 0xfffffff;
struct Edge
{
int pnt;
int dis;
int next;
}edge[E];
int cur;
int neigh[N];
int n, e;
int mindis[N];
int que[N], front, rear;
bool inque[N];
void init()
{
cur = 0;
for (int i = 0; i < n; ++i) neigh[i] = -1;
}
void addedge(int beg, int end, int dis)
{
edge[cur].pnt = end;
edge[cur].dis = dis;
edge[cur].next = neigh[beg];
neigh[beg] = cur;
++cur;
}
void spfa(int s)
{
for (int i = 0; i < n; ++i)
{
mindis[i] = MAX;
inque[i] = false;
}
front = rear = 0;
mindis[s] = 0;
inque[s] = true;
que[rear++] = s;
while (front != rear)
{
int pre = que[front];
inque[pre] = false;
int te = neigh[pre];
while (te != -1)
{
int pnt = edge[te].pnt;
if (mindis[pre] + edge[te].dis < mindis[pnt])
{
mindis[pnt] = mindis[pre] + edge[te].dis;
if (!inque[pnt])
{
inque[pnt] = true;
que[rear++] = pnt;
if (rear == N) rear = 0;
}
}
te = edge[te].next;
}
if (++front == N) front = 0;
}
}
int main()
{
int beg, end, dis;
scanf("%d%d", &e, &n);
init();
for (int i = 0; i < e; ++i)
{
scanf("%d%d%d", &beg, &end, &dis);
--beg;
--end;
addedge(beg, end, dis);
addedge(end, beg, dis);
}
spfa(n - 1);
printf("%d\n", mindis[0]);
return 0;
}