1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4 #include <iostream>
5 #include <queue>
6 #define MAX 9999999
7
8 using namespace std;
9 //pair 的first 保存的为最短距离, second保存的为顶点编号
10 typedef pair<int, int >P;//对组 不知道请自行百度
11
12 struct node
13 {
14 int v, w;//v 为到达的点, w为权重
15 int next;//记录下一个结构体的位置 ,就向链表的next功能是一样的
16 };
17 node edge[2003];//存所有的边,因为是无向图,所以*2
18 int cnt;//结构体的下标
19 int n, s, t;//n 点数,s 起点,t止点
20 int head[203];//和链表的头指针数组是一样的。只不过此处head[u]记录的为最后加入 edge 的且与u相连的边在 edge 中的位置,即下标
21
22 void add(int u, int v, int w)//加边操作
23 {
24 edge[cnt].v = v;
25 edge[cnt].w = w;
26 edge[cnt].next = head[u];//获得下一个结构体的位置
27 head[u] = cnt++;//记录头指针的下标
28 }
29
30 void dijkstra()
31 {
32 int dis[203];//最短路径数组
33 int i, v;//v保存从队列中取出的数的第二个数 也就是顶点的编号
34 priority_queue<P,vector<P>,greater<P> >que;//优先队列 从小到大
35 node e;//保存边的信息,为了书写方便
36 P p;//保存从队列取出的数值
37
38 fill(dis,dis+n,MAX);//初始化,都为无穷大
39 dis[s] = 0;//s—>s 距离为0
40 que.push(P(0,s));//放入距离 为0 点为s
41 while(!que.empty()){
42 p = que.top();//取出队列中最短距离最小的对组
43 que.pop();//删除
44 v = p.second;//获得最短距离最小的顶点编号
45 if(dis[v] < p.first)//若取出的不是最短距离
46 continue;//则进行下一次循环
47 for(i=head[v];i!=-1;i=edge[i].next)//对与此点相连的所有的点进行遍历
48 {
49 e = edge[i];//为了书写的方便。
50 if(dis[e.v]>dis[v]+e.w){//进行松弛
51 dis[e.v]=dis[v]+e.w;//松弛成功
52 que.push(P(dis[e.v],e.v));//讲找到的松弛成功的距离 和顶点放入队列
53 }
54 }
55 }
56 printf("%d\n",dis[t]==MAX?-1:dis[t]);//输出结果
57 }
58
59 int main()
60 {
61 int m, u, v, w;
62
63 while(scanf("%d %d",&n,&m)==2){//获取点数 边数
64 cnt = 0;//结构体下标从0开始
65 memset(head,-1,sizeof(head));//初始化head[N]数组
66 while(m--){
67 scanf("%d %d %d",&u,&v,&w);//获取u,v,w(u,v)
68 add(u,v,w);//加边
69 add(v,u,w);//加边
70 }
71 scanf("%d %d",&s,&t);//获取起止点
72 dijkstra();
73 }
74 return 0;
75 }
题解在此
用到的数据结构 :前向星 对组 优先队列
1 //pair 的first 保存的为最短距离, second保存的为顶点编号
2 typedef pair<int, int >P;//对组 不知道请自行百度
3
4 struct node//前向星存边
5 {
6 int v, w;//v 为到达的点, w为权重
7 int next;//记录下一个结构体的位置 ,就向链表的next功能是一样的
8 };
9 node edge[2003];//存所有的边,因为是无向图,所以*2
10 int head[203];//和链表的头指针数组是一样的。只不过此处head[u]记录的为最后加入 edge 的且与u相连的边在 edge 中的位置,即下标
11
12 priority_queue<P,vector<P>,greater<P> >que;//优先队列 从小到大
在此我们说一下前向星的加边函数
1 void add(int u, int v, int w)//加边操作
2 {
3 edge[cnt].v = v;
4 edge[cnt].w = w;
5 edge[cnt].next = head[u];//获得下一个结构体的位置
6 head[u] = cnt++;//记录头指针的下标
7 }
主函数对数据的获取
1 int main()
2 {
3 int m, u, v, w;
4
5 while(scanf("%d %d",&n,&m)==2){//获取点数 边数
6 cnt = 0;//结构体下标从0开始
7 memset(head,-1,sizeof(head));//初始化head[N]数组
8 while(m--){
9 scanf("%d %d %d",&u,&v,&w);//获取u,v,w(u,v)
10 add(u,v,w);//加边
11 add(v,u,w);//加边
12 }
13 scanf("%d %d",&s,&t);//获取起止点
14 dijkstra();
15 }
16 return 0;
17 }
Dijkstra算法求值
1 void dijkstra()
2 {
3 int dis[203];//最短路径数组
4 int i, v;//v保存从队列中取出的数的第二个数 也就是顶点的编号
5 priority_queue<P,vector<P>,greater<P> >que;//优先队列 从小到大
6 node e;//保存边的信息,为了书写方便
7 P p;//保存从队列取出的数值
8
9 fill(dis,dis+n,MAX);//初始化,都为无穷大
10 dis[s] = 0;//s—>s 距离为0
11 que.push(P(0,s));//放入距离 为0 点为s
12 while(!que.empty()){
13 p = que.top();//取出队列中最短距离最小的对组
14 que.pop();//删除
15 v = p.second;//获得最短距离最小的顶点编号
16 if(dis[v] < p.first)//若取出的不是最短距离
17 continue;//则进行下一次循环
18 for(i=head[v];i!=-1;i=edge[i].next)//对与此点相连的所有的点进行遍历
19 {
20 e = edge[i];//为了书写的方便。
21 if(dis[e.v]>dis[v]+e.w){//进行松弛
22 dis[e.v]=dis[v]+e.w;//松弛成功
23 que.push(P(dis[e.v],e.v));//讲找到的松弛成功的距离 和顶点放入队列
24 }
25 }
26 }
27 printf("%d\n",dis[t]==MAX?-1:dis[t]);//输出结果
28 }