[关闭]
@zhangche0526 2017-02-24T14:59:08.000000Z 字数 3179 阅读 1018

最短路

以下部分内容转载自http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html

Floyed


时间复杂度:

这复杂度……也只有走投无路之时会用到了

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<cstring>
  5. using namespace std;
  6. const int MAXN=100;
  7. int head[MAXN+1],ecnt;
  8. struct node{int to,next,dis;} edge[MAXN+1];
  9. int dis[MAXN+1][MAXN+1];
  10. void add(int x,int y,int qz)
  11. {
  12. ecnt++;
  13. edge[ecnt].to=y;
  14. edge[ecnt].next=head[x];
  15. head[x]=ecnt;
  16. dis[x][y]=qz;
  17. }
  18. bool lt(int x,int y)
  19. {
  20. for(node redge=edge[head[x]];;redge=edge[redge.next])
  21. {
  22. if(redge.to==y) return true;
  23. if(!redge.next) break;
  24. }
  25. return false;
  26. }
  27. int m,n;
  28. void floyed()
  29. {
  30. memset(dis,0x7fffffff,sizeof(dis));
  31. for(int k=1;k<=n;k++)
  32. for(int i=1;i<=n;i++)
  33. for(int j=1;j<=n;j++)
  34. if(dis[i][j]>dis[i][k]+dis[k][j])
  35. dis[i][j]=dis[i][k]+dis[k][j];
  36. }

Dijkstra

时间复杂度

复杂度低且稳定,但不能处理负边权图,最重要的是手写堆优化的Dijkstra洋洋洒洒上百行,易写错

其实Dijkstra与SPFA十分相似,只是Dijkstra通过贪心法减少了不必要的松弛操作

思路:

示例:
1

2

代码:

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<cstring>
  4. using namespace std;
  5. const int MAXINT = 2147483647;
  6. const int MAXN = 1e4,MAXM=5e5;
  7. int dis[MAXN];
  8. int N,M,s;
  9. bool S[MAXN];
  10. int head[MAXN+1],ecnt;
  11. struct node{int next,to,value;} e[MAXM+1];
  12. void add(int x,int y,int z){ecnt++,e[ecnt].to=y,e[ecnt].next=head[x],head[x]=ecnt,e[ecnt].value=z;}
  13. struct dat{int v,id;} heap[2*MAXN+1];int heapSize;
  14. void put(dat x)
  15. {
  16. int now,next;
  17. heap[++heapSize] = x;
  18. now = heapSize;
  19. while(now > 1)
  20. {
  21. next=now >> 1;
  22. if(heap[now].v >= heap[next].v)break;
  23. swap(heap[now],heap[next]);
  24. now = next;
  25. }
  26. }
  27. dat get()
  28. {
  29. int now,next;
  30. dat res;
  31. res = heap[1];
  32. heap[1]=heap[heapSize--];
  33. now = 1;
  34. while(now * 2 <= heapSize)
  35. {
  36. next = now * 2;
  37. if(next < heapSize && heap[next+1].v < heap[next].v)next++;
  38. if(heap[now].v <= heap[next].v) break;
  39. swap(heap[now],heap[next]);
  40. now = next;
  41. }
  42. return res;
  43. }
  44. void Dijkstra(int v0)
  45. {
  46. int i;
  47. for(i=1;i<=N;i++) dis[i]=MAXINT;
  48. memset(S,false,sizeof(S));
  49. for(int tmp=head[v0];tmp;tmp=e[tmp].next)
  50. {
  51. dis[e[tmp].to]=e[tmp].value;
  52. dat x;
  53. x.id=e[tmp].to,x.v=dis[e[tmp].to];
  54. put(x);
  55. }
  56. dis[v0] = 0;
  57. S[v0] = true;
  58. for(i=2; i<=N; i++)
  59. {
  60. int u;
  61. do u=get().id;
  62. while(S[u]);
  63. S[u] = true;
  64. for(int tmp=head[u];tmp;tmp=e[tmp].next)
  65. if(!S[e[tmp].to])
  66. if(dis[u]+e[tmp].value<dis[e[tmp].to])
  67. {
  68. dis[e[tmp].to]=dis[u]+e[tmp].value;
  69. dat x;
  70. x.v=dis[e[tmp].to],x.id=e[tmp].to;
  71. put(x);
  72. }
  73. }
  74. }

SPFA

时间复杂度:
不太稳定,但能处理负边权图

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. using namespace std;
  5. const int MAXINT=2147483647;
  6. const int MAXN=10000,MAXM=500000;
  7. int n,m,s;
  8. int head[MAXN+1],ecnt;
  9. struct node{int to,next,value;} edge[MAXM+1];
  10. void add(int x,int y,int z)ecnt++,edge[ecnt].to=y,edge[ecnt].next=head[x],head[x]=ecnt,edge[ecnt].value=z;}
  11. bool vis[MAXN+1];
  12. int dis[MAXN+1],queue[2*MAXN+5];
  13. int SPFA(int v0)
  14. {
  15. memset(vis,false,sizeof(vis));
  16. for(int i=1;i<=n;i++) dis[i]=MAXINT;
  17. dis[v0]=0;
  18. vis[v0]=true;
  19. int h=0,t=1;
  20. queue[t]=v0;
  21. while(h<t)
  22. {
  23. h=(h+1)%(2*n+5);//循环队列出队
  24. int u=queue[h];
  25. vis[u]=false;
  26. for(int tmp=head[u];tmp;tmp=edge[tmp].next)
  27. if(dis[edge[tmp].to]>dis[u]+edge[tmp].value)
  28. {
  29. dis[edge[tmp].to]=dis[u]+edge[tmp].value;
  30. if(!vis[edge[tmp].to])
  31. {
  32. vis[edge[tmp].to]=true;
  33. t=(t+1)%(2*n+5);//循环队列入队
  34. queue[t]=edge[tmp].to;
  35. }
  36. }
  37. }
  38. }
  39. int main()
  40. {
  41. freopen("spfa.in","r",stdin);
  42. cin>>n>>m>>s;
  43. int u,v,w;
  44. for(int i=1;i<=m;i++)
  45. {
  46. cin>>u>>v>>w;
  47. add(u,v,w);
  48. add(v,u,w);
  49. }//读入
  50. SPFA(s);
  51. for(int i=1;i<n;i++) cout<<dis[i]<<" ";//输出
  52. cout<<dis[n]<<endl;
  53. return 0;
  54. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注