[板子]Floyd&Dijkstra

bellman和spfa就不挂了因为noip不考

Floyd算法:

  默认是业界最短路最简单的写法,并且只有五行。时间复杂度为O(N3),空间复杂度为O(N2)。

1 for(int k=1;k<=n;k++){
2     for(int i=1;i<=n;i++){
3         for(int j=1;j<=n;j++){
4             if(f[i][j]>f[i][k]+f[k][j]){
5                 f[i][j]=f[i][k]+f[k][j];
6             }
7         }
8     }
9 }

 

  简单来说就是通过另一个点个点来收缩一个点到一个点的距离,如果f[i][j]>f[i][k]+f[k][j]的话就把f[i][j]变成f[i][k]+f[k][j]

  emm...再简单的一个例子就是(1,2)=10,但是(1,3)+(3,2)=5,那么就可以通过点3把(1,2)的距离变为5。

  还是很简单的吧...

 

Dijkstra算法:

 

  刚刚的Floyd能够通过空间复杂度为On3的方法算出所有点到所有点的最短路,但是这样做在某些题目中会炸掉或者T掉,那么怎么解决单源最短路径?

  (其实所有的最短路径都可以从啊哈磊先生的啊哈算法中找到详细讲解)

 

  在我理解下的Dijkstra分为以下几个部分:

  1、在二维图中标记已知路径,将位置路径设为inf

 1 for(int i=1;i<=n;i++){
 2         for(int j=1;j<=n;j++){
 3             if(i==j){
 4                 a[i][j]=0;
 5             }else{
 6                 a[i][j]=inf;
 7             }
 8         }
 9     }
//inf一般为0xf
10 for(int i=1;i<=m;i++){ 11 int v,r,w; 12 scanf("%d%d%d",&v,&r,&w); 13 if(a[v][r]>w){ 14 a[v][r]=w; 15 }//这里一定要注意是否为有向边还是无向 16 17 }

2、数组dis和数组book

1     for(int i=1;i<=n;i++){
2         f[i]=a[1][i];
3     }
4     b[1]=1;

3、主要算法:

 1     for(int i=1;i<=n;i++){
 2         int minx=inf,u=0;
 3         for(int j=1;j<=n;j++){
 4             if(!b[j]&&f[j]<minx){
 5                 minx=f[j];
 6                 u=j;
 7             }
 8         }
 9             b[u]=1;
10             for(int j=1;j<=n;j++){
11                 if(!b[j]){
12                     if(f[j]>f[u]+a[u][j]){
13                         f[j]=f[u]+a[u][j];
14                     }
15                 }
16             }
17     }

解释以下:book数组用来记录松弛每个边,然后在循环每一个点中依次松弛从这个点到其他最小一个点的路径长短,比如前7行就是在找距离1号最短距离的X号,然后对X号松弛

第九行将准备松弛的点固定,然后松弛其它边。

 

应该是比较难理解的..不过多做几道题就差不多会写了。

题目:洛谷1576,2384

 

posted @ 2017-11-09 14:57  Fylsea  阅读(420)  评论(0编辑  收藏  举报