最短路概念

刚刚一不小心被自己删了重写

短路习题hdu 2544  2112 1874 1596  poj 1789戳点击打开链接

大家知道最短路的算法有很多种吧,现在我来总结下:

对于无向正权图,我们可以用

dijkstar算法:不可以处理负权图,,要注意与最小生成树中的普莱姆算法中的不同之处

 

void dijkstar(){    //int prime()
    int i,j,k,min;  //int sum=0;
    for(i=0;i


floyd算法:核心代码如下

 

 

int i,j,k;
for (k=0;k


但是这里我们要注意循环的嵌套顺序,如果把检查所有节点K放在最内层,那么结果将是不正确的,为什么呢?因为这样便过早的把i到j的最短路径确定下来了,而当后面存在更短的路径时,已经不再会更新了。

 

Bellman算法:

void bellman_ford()
{
    int i,j,dis[203];
    bool flag;//用于优化的
    memser(dist,MAX,dist+n);///初始化
    dis[s]=0;   //源点初始化为0
        m=m*2;  //此处和m = 2*m是一样的,因为建立的无向图
    for(i=1;iu.d+w(u,v))
            if(dis[edge[j].u]>dis[edge[j].v]+edge[j].w){//进行松弛
                 dis[edge[j].u] = dis[edge[j].v]+edge[j].w;
                 flag = true;//松弛成功
             }
         }
         if(flag!=true)  //若所有的边i的循环中没有松弛成功的
             break;
        ///此优化可以大大提高效率。
     }
     printf("%d\n",dis[t]==MAX?-1:dis[t]);//输出结果
 }

SPAF算法:要用到队列

 

//第一步://无向图,一条无向边看为两条有向边
void SPFA(int start)
{
  queueq;
  int i,u;
  memset(vis,0,sizeof(vis));    memset(dis,inf,sizeof(dis));
  dis[start]=0;
  q.push(start);    vis[start]=1;
  //第二步:在队列中取点,把其vis状态设为0,对该点相邻的点(连接二者的边)进行松弛操作,修改相邻点的dis[]
  //并判断相邻的点vis[]状态是否为0(不存在于队列中),如果是,将其加入到队列中
  while(!q.empty())
  {
    u=q.front(); q.pop();    vis[u]=0;
    ///松弛
    for(i=1;i<=n;i++)
      if(dis[u]+mapp[u][i]

 

 

 

 

 

你可能感兴趣的:(算法)