最短路-Dijstra算法和spfa算法模板

一:Dijstra模板

给定一个n个点m条边的有向图,图中可能存在重边和自环,所有边权均为正值。

请你求出1号点到n号点的最短距离,如果无法从1号点走到n号点,则输出-1。

输入格式

第一行包含整数n和m。

接下来m行每行包含三个整数x,y,z,表示存在一条从点x到点y的有向边,边长为z。

输出格式

输出一个整数,表示1号点到n号点的最短距离。

如果路径不存在,则输出-1。

数据范围

1≤n≤5001≤n≤500,
1≤m≤1051≤m≤105,
图中涉及边长均不超过10000。

输入样例:

3 3
1 2 2
2 3 1
1 3 4

输出样例:

3

 思路:

               最短路-Dijstra算法和spfa算法模板_第1张图片

                                    最短路-Dijstra算法和spfa算法模板_第2张图片最短路-Dijstra算法和spfa算法模板_第3张图片

 

#include 
#include 
#include 

using namespace std;

const int N=510;
int g[N][N];

bool st[N]; //用于在更新最短距离时 判断当前的点的最短距离是否确定 是否需要更新
int dist[N];//用于存储每个点到起点的最短距离
int n,m;

int Dijstra()
{
    memset(dist,0x3f,sizeof dist);
    
    dist[1]=0;

    for(int i=0;idist[j]))
             t=j;
             
        //更新最短距离的点到其他点的距离
        for(int j=1;j<=n;j++)
            dist[j]=min(dist[j],dist[t]+g[t][j]);
            
        st[t]=true;
    }
    
    if(dist[n]==0x3f3f3f3f) return -1;
    
    return dist[n];
}

int main()
{
    
    cin>>n>>m;
    memset(g,0x3f,sizeof g);
    memset(st,0,sizeof st);
    
    for(int i=0;i>a>>b>>c;
        g[a][b]=min(g[a][b],c);
    }
    
    int t=Dijstra();
    
    cout<

 

 

SPFA算法模板:

例题:

给定一个n个点m条边的有向图,图中可能存在重边和自环, 边权可能为负数

请你求出1号点到n号点的最短距离,如果无法从1号点走到n号点,则输出impossible。

数据保证不存在负权回路。

输入格式

第一行包含整数n和m。

接下来m行每行包含三个整数x,y,z,表示存在一条从点x到点y的有向边,边长为z。

输出格式

输出一个整数,表示1号点到n号点的最短距离。

如果路径不存在,则输出”impossible”。

数据范围

1≤n,m≤1051≤n,m≤105,
图中涉及边长绝对值均不超过10000。

输入样例:

3 3
1 2 5
2 3 -3
1 3 4

输出样例:

2

 思路:

        SPFA 算法是 Bellman-Ford算法 的队列优化算法的别称,通常用于求含负权边的单源最短路径,以及判负权环。SPFA一般情况复杂度是O(m)O(m) 最坏情况下复杂度和朴素 Bellman-Ford 相同,为O(nm)O(nm)。

 2、spfa算法步骤
 queue <– 1
while queue 不为空
 (1) t <– 队头
 queue.pop()
 (2)用 t 更新所有出边 t –> b,权值为w
 queue <– b (若该点被更新过,则拿该点更新其他点)

时间复杂度 一般:O(m) 最坏:O(nm)
n为点数,m为边数

 

#include 
#include 
#include 
#include 

using namespace std;
const int N=100010;

int h[N],e[N],ne[N],w[N],idx;

bool st[N];
int dist[N];
int n,m;

void add(int a,int b,int c)
{
    e[idx]=b;
    ne[idx]=h[a];
    w[idx]=c;
    h[a]=idx++;
}
int spfa()
{
    
    memset(dist,0x3f,sizeof dist);
    //初始化,将1号点放入队列
    dist[1]=0;
    queue q;
    q.push(1);
    st[1]=true;
    while(q.size())
    {
        int t=q.front();
        q.pop();
        st[t]=false;
        
        for(int i=h[t];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(dist[j]>dist[t]+w[i])
            {
                dist[j]=dist[t]+w[i];
                if(!st[j])
                {
                    q.push(j);
                    st[j]=true;
                }
            }
        }
    }
    if(dist[n]==0x3f3f3f3f) return -1;
    return dist[n];
}


int main()
{
    scanf("%d%d",&n,&m);
    //初始化邻接表
    memset(h,-1,sizeof h);
    
    for(int i=0;i

 

 

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