就是求1到n的最短路径;输入是n,m;然后是m条边的信息
算法如下:
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int N = 10010;
int n, m;
int h[N], e[N], ne[N],w[N],idx;
int dist[N];
int ans = N;
//邻接表存储,每个结点都会有一个链表
//h[i]存的是i号链表头指向哪个结点,指向null的话就是-1
//e来存这条边指向哪个结点,1指向2,则存2
//w来存这条边的权值是多少,1指向2且权值为10,则存10
//ne来存链表上下一个是几号结点
//idx表示现在用到了哪个下标
typedef pair<int,int> PII;
bool st[N];
void add(int a, int b,int c) //添加一条从结点a到结点b的边,权值为c
{//在a链表的表头插入
e[idx] = b; //先将b存入结点idx中
w[idx] = c; //c是a指向b这条边的权值
ne[idx] = h[a]; //将idx结点的指针指向h原本指向的地方
h[a] = idx;//将h指向新加进来的这个idx结点上
idx++;
}
int dijkstra()
{
memset(dist, 0x3f, sizeof dist);
dist[1] = 0;
priority_queue < PII, vector<PII>, greater<PII>>heap; //一个优先队列,默认是大根堆less,greater是小根堆
heap.push({ 0,1 });//第一个结点的内容;(起点到该点的距离值,结点编号)
while (heap.size())
{
auto t = heap.top(); //取出最小的顶点作为中间结点,第一次就是即1号结点自己
heap.pop();//从堆中删掉
int distance = t.first, ver = t.second; //t的第一个元素是从原点到结点编号的距离,第二个元素是结点编号
if (st[ver]) continue;
for (int i = h[ver]; i != -1; i = ne[i]) //现在ver号结点是中间结点,要利用这个中间结点来更新整个dist
{//遍历这一个链表,不要想的这么具体,就是遍历一个单链表,
//每个结点两个值,一个编号e[i],一个从表头结点到该节点的距离w[i]
int j = e[i];
if (dist[j] > distance + w[i])
{
dist[j] = distance + w[i];
heap.push({ dist[j], j });
}
}
}
if (dist[n] == 0x3f3f3f3) return -1;
return dist[n];
}
int main()
{
scanf_s("%d %d", &n, &m);//几个点 几条边
memset(h, -1, sizeof h); //每个链表的表头都指向null
int a, b, c;
while (m--)
{
scanf_s("%d%d%d", &a, &b, &c);
add(a, b, c);
}
int d = dijkstra();
printf("%d\n", d);
}
/*
5 7
1 2 19
1 4 20
2 3 15
3 5 16
4 2 18
2 3 14
4 5 13
*/