题目链接:https://www.cometoj.com/problem/1638
最短路伪代码:
STL优先队列的使用:https://blog.csdn.net/disguise666/article/details/85989788
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
const int MaxV = 100005;
typedef long long ll;
ll dist[MaxV]; //记录单源最短路径
bool vis[MaxV]; //标记是否访问
int n, m, k, h[MaxV], maxh;
struct node{
int i;
ll Data;
node(int a, ll b){
i = a;
Data = b;
}
};
struct cmp{
bool operator ()(const node n1, const node n2){
return n1.Data > n2.Data;
}
};
priority_queue<node, vector<node>, cmp> q;
typedef struct ENode{
int v1, v2;
ll Weight;
} * Edge;
struct AdjVNode{
int AdjV;
ll Weight;
AdjVNode *Next;
};
typedef struct VNode
{
AdjVNode *FirstEdge;
//int Hight; //顶点权重(高)
} AdjList[MaxV];
typedef struct GNode
{
int Nv, Ne;
AdjList L;
} * LGraph;
LGraph CreateGraph(int Nv)
{
LGraph G = new GNode();
G->Nv = Nv;
return G;
}
void DeleteGraph(LGraph G)
{
AdjVNode *A;
for (int i = 1; i <= G->Nv; i++)
while (G->L[i].FirstEdge)
{
A = G->L[i].FirstEdge;
G->L[i].FirstEdge = A->Next;
delete A;
}
delete G;
}
void InsertEdge(Edge E, LGraph G)
{
AdjVNode *A = new AdjVNode;
A->AdjV = E->v2, A->Weight = E->Weight;
A->Next = G->L[E->v1].FirstEdge;
G->L[E->v1].FirstEdge = A;
}
void Dijkstra(int start, LGraph G)
{
memset(dist, 0x3f, sizeof(dist));
q.push(node(start, 0)); //优先队列存 终点i与权重Weight, 还要一个起点数据head[]
dist[start] = 0;
AdjVNode *A;
while (!q.empty())
{
int v = q.top().i; //起点
q.pop();
if(vis[v]) //该点的最短路径已确定, 不用再重复操作
continue;
vis[v] = true; //已访问的意思是: 该点的单源最短路径已确定
A = G->L[v].FirstEdge;
while (A) //访问v为起点的每一条边
{
if(!vis[A->AdjV]) //如果没有确定最短路径
if(dist[v] + A->Weight < dist[A->AdjV])
dist[A->AdjV] = dist[v] + A->Weight, q.push(node(A->AdjV, dist[A->AdjV]));
A = A->Next;
}
}
}
int main()
{
cin >> n >> m >> k;
LGraph G = CreateGraph(n);
for (int i = 1; i <= n; i++)
cin >> h[i];
Edge E = new ENode;
maxh = h[1] + k;
int x, y;
ll z;
for (int i = 1; i <= m; i++)
{
cin >> x >> y >> z;
ll lx = max(0, h[x] - maxh);
ll ly = max(0, h[y] - maxh);
E->v1 = x, E->v2 = y, E->Weight = z + ly * ly;
InsertEdge(E, G);
E->v1 = y, E->v2 = x, E->Weight = z + lx * lx;
InsertEdge(E, G);
}
Dijkstra(1, G);
cout << dist[n] << endl;
DeleteGraph(G);
return 0;
}