后知后觉的我今天终于搞明白了dijkstra算法,exciting!
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <queue>
#define inf 0x3f3f3f3f
using namespace std;
int k = 1, n; //K是新加入的边的结构数组下标,加入一个便+1
struct ver {
int dis;
int visit;
int path;
int adj = 0;
}vertex[100]; //表示顶点的数组,因为边是从1开始记录,初始化全部为0的作用相当于NULL,标记邻接表这一行的结束
struct lin { //表示边的结构体
int to;
int next;
int length;
}line[1000];
struct cmp {
bool operator ()(int x, int y)
{
return vertex[x].dis > vertex[y].dis;
}
};
priority_queue<int, vector<int>, cmp > q;//建立优先队列q
void build(int start, int end, int length);//建表函数
void ini(int begin); //初始化函数
void dijkstra(int begin);
void print(int destination); //打印路径函数
int main() {
int i, start, end, length;
int begin, destination; //最短路的起点
printf("输入边数:");
scanf("%d", &n); //输入边数
printf("输入起点:");
scanf("%d", &begin);
ini(begin);
for (i = 0; i < n; i++) {
printf("再输入%d条边", n - i);
scanf("%d %d %d", &start, &end, &length); //输入边的起点终点
build(start, end, length); //建立邻接表
}
dijkstra(begin);
while (scanf("%d", &destination) != EOF) {
print(destination);
}
}
void build(int start, int end, int length) {
line[k].next = vertex[start].adj; //将已知的该顶点的边的位置接到新加入的这条边的后面
line[k].to = end; //录入此条边的终点
line[k].length = length;
vertex[start].adj = k; //将该顶点邻接的下一条边更新为此边
k++; //k++,等待输入下一条边
return;
}
void ini(int begin) {
int i;
memset(line, 0, sizeof(line));
for (i = 0; i < 100; i++) {
vertex[i].dis = inf;
vertex[i].adj = 0;
vertex[i].visit = 0;
vertex[i].path = 0;
}
vertex[begin].dis = 0;
}
void dijkstra(int begin) {
q.push(begin);
int v, i, t;
for (;;) {
if (q.empty()) break;
v = q.top();
q.pop();
vertex[v].visit = 1;
for (i = vertex[v].adj; i != 0; i = line[i].next) {
t = line[i].to;
if (!vertex[t].visit) {
if (vertex[v].dis + line[i].length < vertex[t].dis) {
vertex[t].dis = vertex[v].dis + line[i].length;
vertex[t].path = v;
}
q.push(t);
}
}
}
}
void print(int destination) {
if (vertex[destination].path != 0) {
print(vertex[destination].path);
printf(" to");
}
printf("%d", destination);
}