Dijkstra求单源最短路模板

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 }

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值