Los dos más breve resumen algoritmo de ruta

Más corto algoritmo de ruta

Resumimos aquí sólo los más de dos algoritmo del camino más corto, el primero es: Dijkstra, y la segunda es: SPFA;

Ambos algoritmos utilizan la optimización de colas, Dijkstra es una cola de prioridad, es SPFA cola normal;


Dijkstra

Presentado por primera vez en primer lugar, y el más utilizado del algoritmo del camino más corto: Dijkstra;

Idea de este algoritmo se basa en un determinado punto de partida de s, s para encontrar el punto de este punto se puede conectar, se puede actualizar la ruta que conecta los puntos, y luego en el interior de cola de prioridad; cola de prioridad mantiene dos cosas, una este es el punto de partida s a punto peso camino, la etiqueta es un punto;

El enfoque aquí decir que es correcto para el lado negativo del proceso, por un lado negativo derecha, Dijkstra no se procesa,

Por ejemplo:
1-2 en peso de 1
2-3 valor de peso de -3
3-1 con un peso de 2

El Dijkstra cada punto atravesada sólo una vez, por lo que el camino más corto es de 1-2 1, en lugar de 1; cada borde por supuesto asegurarse de que el pie más corta sólo una vez;

plantilla de Dijkstra:

struct queue_element
{
    int x,y,dis_value;
    queue_element(int x_,int y_,int dis_value_):
        x(x_),y(y_),dis_value(dis_value_){}
    bool operator < (const queue_element &other) const
    {
        return dis_value>other.dis_value;
    }
};
inline void dijkstra()//可以不带参数,也可以把起点带进来
{
    priority_queue<element> q;//优先队列大法吼
    q.push(element(1,0));//把起点压进去
    while(!q.empty())//不空就说明还有点没搜完
    {
        element k=q.top();//取出队首
        q.pop();
        if(vis[k.node])//如果已经在集合中(被搜到过)
            continue;//扔掉
        vis[k.node]=1;//标记
        dis[k.node]=k.value;//存下最短路(由于优先队列的排序已经相当于完成了松弛,所以这就是答案)
        for(vector<edge>::iterator it=v[k.node].begin();it!=v[k.node].end();++it)//用指针遍历邻接表
            q.push(element(it->node,it->weight+k.value));//松弛
    }
}

SPFA

Permítanme hablar de aquí, a menos que exista un lado derecho negativo y un anillo negativa a utilizar SPFA, el otro no, y no lo use;

el algoritmo de Dijkstra y esta diferencia todavía es cada vez más grande:

  1. Cola en lugar de priority_queue;
  2. Cuando un punto fuera del equipo, para limpiarlo de la marca, para asegurarse de que se puede recorrer de nuevo;
  3. Contar el número de Traverse cada punto, si el tiempo es mayor que o igual a N, lo que indica un anillo negativa;

Aquí no es explicar la profundidad de este algoritmo:

bool SPFA()
{
    queue<int> q;//队列
    memset(dis,127/3,sizeof(dis));//初始化一个很大的数
    dis[s]=0;//原点最短路是0
    q.push(s);//原点入队
    vis[s]=1;//标记入队
    while(!q.empty())//队列不空说明没跑完
    {
        int k=q.front();//取出队首
        q.pop();
        vis[k]=0;//擦去标记
        ++cnt[k];//统计次数
        if(cnt[k]>=n)//如果超过n-1说明有负环
            return 0;//报错
        for(vector<edge>::iterator it=v[k].begin();it!=v[k].end();++it)//邻接表遍历相连的边
            if(dis[it->node]>dis[k]+it->weight)//如果可以松弛
            {
                dis[it->node]=dis[k]+it->weight;//松弛
                if(!vis[it->node])//如果被松弛的点不在队列里
                {
                    vis[it->node]=1;//标记入队
                    q.push(it->node);//入队
                }
            }
    }
    return 1;//顺利完成
}
Publicados 264 artículos originales · alabanza won 46 · Vistas a 10000 +

Supongo que te gusta

Origin blog.csdn.net/qq_44291254/article/details/104901054
Recomendado
Clasificación