当前位置:   article > 正文

C++语言(单源最短路)_#include bool a[10000002]; vector s

#include bool a[10000002]; vector sieve(int n) { vector

只有一丢~的代码(附加一些不知道对不对的口胡)

至于图吗,,,,,我想后期我会补上~只是我想~~~~

先贴上

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<string.h>
  4. #define Tnf 2147483647
  5. /*
  6. fist[一个点x]=边 表示x这个点连接的第一条边是谁
  7. next[一条边mm]=边kk 表示mm这条边连接的下一条边的名字叫kk
  8. to[一条边xx]=一个点y1 表示xx这条边连向的点是y1
  9. weight[一条边]=一个值, 是表示这个边的权值
  10. */
  11. using namespace std;
  12. int n,m,s;
  13. long long int dis[500001],next[500001],head[500001],book[500001],to[500001],w[500001],tot=0;
  14. void add(int a,int b,int c)
  15. {
  16. /*要知道,邻接表中(加边操作)只能是通过第一条边是谁来查找,要想插入每一条边,只能是通过不断的更新第一条便来实现的,先让现在插入的边连接目前该电
  17. 的第一条边,然后把应该插入的点视为该点的第一条边*/
  18. tot++;
  19. to[tot]=b;
  20. w[tot]=c;
  21. next[tot]=head[a];
  22. head[a]=tot;
  23. }
  24. /*
  25. dijkstra 的一般步骤,1.从一个点开始搜索,不断计算长度(先初始化,如果两路不通,直接输出最大值即可,speciallist dis这个数组也是会因为开始的源点不同而变化,每次都更新还是有必要的)
  26. 2.每一次都是从不同的点进行的dijkstra,所以每一次的标记与否的点都是不一样的,应该每次都清空book标记数组(这个地方要注意啊string.h)
  27. 3.(这些都是小事,应该会记住)首先计算dijkstra的时候,应该吧这个标记的点到自己的距离设为0
  28. 4.按顺序依次找每一个点的最小dis,(for循环依次找就OK了)
  29. 5.注意在找的过程中,首先要明确的是★开始要找的点一定是没有找过的点啊,★这个点的dis一定是连接出发点中最小的点(不然的话,那这个点去松弛,这个点既然不是最小的点
  30. 去松弛也没啥意思,问题是,松弛完了,结果是错的....还要注意的是,找的最小的点以后加入集合,即打上标记,) ★找到了这个符合要求的点进行松弛操作就可以了
  31. */
  32. void dijkstra(int u)
  33. {
  34. // memset(dis,Tnf,sizeof(dis));
  35. for(int i=1;i<=n;i++)dis[i]=Tnf;
  36. memset(book,0,sizeof(book));
  37. dis[u]=0;
  38. for(int i=1;i<=n;i++)
  39. {
  40. int start=-1;
  41. for(int j=1;j<=n;j++)
  42. {
  43. if(book[j]==0&&(dis[j]<dis[start]||start==-1))start=j;
  44. }
  45. book[start]=1;
  46. for(int e=head[start];e;e=next[e])
  47. {
  48. dis[to[e]]=min(dis[to[e]],dis[start]+w[e]);
  49. }
  50. }
  51. }
  52. int main()
  53. {
  54. scanf("%d%d%d",&n,&m,&s);
  55. for(int i=0;i<m;i++)
  56. {
  57. int a,b,c;
  58. scanf("%d%d%d",&a,&b,&c);
  59. add(a,b,c);
  60. }
  61. dijkstra(s);
  62. for(int i=1;i<=n;i++)cout<<dis[i]<<" ";
  63. }
  64. /*
  65. make a summary
  66. 其一 错误很明显了 ,每次都是忘记找该点连接的最小的一条边,然后就乱松弛,结果全wa
  67. 其二 在松弛时 e=haed[start];e;e=next[e] 以及dis[to[e]]=min(dis[top[e]],dis[start]+w[e]) (也就是核心代码记得一点都不熟)
  68. */

本人比较喜欢邻接表 ~~邻接矩阵也似很好啊 map[a][b]=c;

以下是堆优化以后的(用来对付升级版的~~~)

  1. #include<queue>
  2. #include<cstdio>
  3. #include<stdio.h>
  4. #include<iostream>
  5. #include<string.h>
  6. using namespace std;
  7. int tot=0,next[100100002],w[1000002],to[1000002],first[10000002], vis[10000002], dis[10000002];
  8. struct node
  9. {
  10. int d,id;
  11. bool operator <(const node &a)const
  12. {
  13. return d>a.d;
  14. }
  15. };
  16. void add(int a,int b,int c)
  17. {
  18. tot++;
  19. next[tot]=first[a];
  20. to[tot]=b;
  21. w[tot]=c;
  22. first[a]=tot;
  23. }
  24. priority_queue<node> q;
  25. void dijkstra(int s)
  26. {
  27. memset(dis,0x7f,sizeof(dis));
  28. dis[s]=0;
  29. q.push((node){0,s});
  30. while(!q.empty())
  31. {
  32. int x=q.top().id;
  33. q.pop();
  34. if(vis[x])continue;
  35. vis[x]=1;
  36. for(int i=first[x];i;i=next[i])
  37. {
  38. int y=to[i];
  39. if(vis[y])continue;
  40. if(dis[y]>dis[x]+w[i])
  41. {
  42. dis[y]=dis[x]+w[i];
  43. q.push((node){dis[y],y});
  44. }
  45. }
  46. }
  47. }
  48. int main()
  49. {
  50. int n,m,s;
  51. scanf("%d%d%d",&n,&m,&s);
  52. for(int i=1;i<=m;i++)
  53. {
  54. int a,b,c;
  55. scanf("%d%d%d",&a,&b,&c);
  56. add(a,b,c);
  57. }
  58. dijkstra(s);
  59. for(int i=1;i<=n;i++)cout<<dis[i]<<" ";
  60. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/243574
推荐阅读
相关标签
  

闽ICP备14008679号