最短路SPFA算法(解决负权边)

算法思想:

实现方法:

  建立一个队列,初始时队列里只有起始点,再建立一个表格记录起始点到所有点的最短路径(该表格的初始值要赋为极大值,该点到他本身的路径赋为0)。然后执行松弛操作,用队列里有的点作为起始点去刷新到所有点的最短路,如果刷新成功且被刷新点不在队列中则把该点加入到队列最后。重复执行直到队列为空。

第一种用邻接表实现

#include <iostream>
#include <memory.h>
#include <bits/stdc++.h>
using namespace std;
const int IN = (1<<28);
int N,M,S,T;
struct node
{
    int v,w;
};
vector <node> G[100005];
int dist[100005];
int visited[100005];
queue <int> q;
void SPFA()
{
    for( int i = 1; i <= N; i++ )
    {
        if( i==S )
            dist[i] = 0;
        else
            dist[i] = IN;
    }
    memset(visited, 0, sizeof(visited));
    visited[S] = 1;
    q.push(S);
    while( !q.empty() )
    {
        int now = q.front();
        q.pop();
        visited[now] = 0;
        for( int i = 0; i < G[now].size(); i++ )
        {
            if( dist[ G[now][i].v ] > dist[now] + G[now][i].w )
            {
                dist[ G[now][i].v ] = dist[now] + G[now][i].w ;
                if( !visited[ G[now][i].v ] )
                {
                    q.push( G[now][i].v );
                    visited[ G[now][i].v ] = 1;
                }
            }
        }
    }
}
int main()
{
    cin >> N >> M >> S >> T;
    while( M-- )
    {
        int Begin,End,Length;
        cin >> Begin >> End >> Length;
        node temp;
        temp.v = End; temp.w = Length;
        G[Begin].push_back( temp );
        temp.v = Begin; temp.w = Length;
        G[End].push_back( temp );
    }
    SPFA();
    cout << dist[T] << endl;
    return 0;
}
die
第二种用邻接矩阵实现
#include <iostream>
#include <memory.h>
#include <bits/stdc++.h>
using namespace std;
const int IN = (1<<28);
int N,M,S,T;
int G[1005][1005];
int b[1005][1005];
int dist[1005];
int visited[1005];
queue <int> q;
void SPFA()
{
    for( int i = 1; i <= N; i++ )
    {
        if( i==S )
            dist[i] = 0;
        else
            dist[i] = IN;
    }
    memset(visited, 0, sizeof(visited));
    visited[S] = 1;
    q.push(S);
    while( !q.empty() )
    {
        int now = q.front();
        q.pop();
        for( int i = 1; i <= b[now][0]; i++ )
        {
            if( dist[ b[now][i] ] > dist[now] + G[now][ b[now][i] ] )
            {
                dist[ b[now][i] ] = dist[now] + G[now][ b[now][i] ];
                if( !visited[ b[now][i] ] )
                {
                    q.push( b[now][i] );
                    visited[ b[now][i] ] = 1;
                }
            }
        }
    }
}
int main()
{
    cin >> N >> M >> S >> T;
    for( int i = 1; i <= N; i++ )
    {
        b[i][0] = 0;
        for( int j = 1; j <= N; j++ )
        {
            if( i==j )
                G[i][j] = 0;
            else
                G[i][j] = IN;
        }
    }
    while( M-- )
    {
        int Begin,End,Length;
        cin >> Begin >> End >> Length;
        if( G[Begin][End] > Length )
        {
            b[Begin][0] ++ ;
            b[Begin][ b[Begin][0] ] = End;
            b[End][0] ++;
            b[End][ b[End][0] ] = Begin;
            G[Begin][End] = Length;
            G[End][Begin] = Length;
        }
    }
    SPFA();
    cout << dist[T] << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/xutian_curry/article/details/80200158