蓝桥杯--最短路 -- Djikstra,Bellman-Frod,SPFA

来源:互联网 发布:删除微信应用数据内存 编辑:程序博客网 时间:2024/06/03 20:09
问题描述

给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环)。请你计算从1号点到其他点的最短路(顶点从1到n编号)。

输入格式

第一行两个整数n, m。

接下来的m行,每行有三个整数u, v, l,表示u到v有一条长度为l的边。

输出格式
共n-1行,第i行表示1号点到i+1号点的最短路。
样例输入
3 3
1 2 -1
2 3 -1
3 1 2
样例输出
-1
-2
--------------------------------
Djistra:缺点,无法计算带负权路径
#include<iostream>#include<cstdlib>#define MAX 20005 using namespace std;int main(){    int infinity = 99999999;    int n,m;    int book[MAX] = {0};    int dis[MAX];    cin>>n;    int **arr;//Dynamic definition of two-dimensional array    arr = (int **)malloc((n+1)*sizeof(int *));//assign n+1 rows     for(int i = 0; i < (n+1); i++){//allocate n space for each rows        arr[i] = (int *)malloc((n+1)*sizeof(int));    }    for( int i = 1; i <= n; i++ ){//initialization adjacency matrix        for(int j = 1; j <= n; j++){            if( i == j) arr[i][j] = 0;            else arr[i][j] = infinity;        }    }    int u,v,l;    cin>>m;//enter the edge    for(int i = 0; i < m; i++){        cin>>u>>v>>l;        arr[u][v] = l;    }    //the distance from the vertex one to other vertex    for(int i = 1; i <= n; i++)        dis[i] = arr[1][i];        book[1] = 1;//vertex one has visited    //the core of Dijkstra alogrithm     int min;     for (int i = 1; i < n; i++){        min = infinity;        for(int j = 1; j <= n; j++){//find the closest point to the vertex one            if(book[j] == 0 && dis[j] < min){                min = dis[j];                u = j;            }        }        book[u] = 1;        for( v = 1; v <= n;v++){            if(arr[u][v] < infinity){                if(dis[u] + arr[u][v] < dis[v])                    dis[v] = dis[u] + arr[u][v];            }        }    }    for(int i = 2; i <= n; i++ )            cout<<dis[i]<<endl;    return 0;}
Bellman-Frod:优点:可以计算带负权路径
              缺点:时间复杂度(time complexity)太高 
#include<iostream> #include<cstdlib>using namespace std;int main(){    int infinity = 99999999;    int n,m;    cin>>n>>m;    int *u;    int *v;    int *w;    u = (int *)malloc((m+1)*sizeof(int));    v = (int *)malloc((m+1)*sizeof(int));    w = (int *)malloc((m+1)*sizeof(int));    for(int i = 1; i <= m; i++){        cin>>u[i]>>v[i]>>w[i];    }    int *dis;    dis = (int *)malloc((n+1)*sizeof(int));    for(int i = 1; i <= n; i++){        dis[i] = infinity;    }    dis[1] = 0;    //bellman-ford algorithm    for(int k = 1; k <= n-1; k++){        for(int i = 1; i <= m;i++){            if(dis[u[i]] + w[i] < dis[v[i]] ){                dis[v[i]] = dis[u[i]] + w[i];            }        }    }        for(int i = 2; i <= n; i++){        cout<<dis[i]<<endl;    }    return 0;}
 SPFA:Shortest Path Faster Algorithm,又名Bellman-Frod算法的队列优化
       优点:可以计算带负权路径,大大缩短时间复杂度 
#include<iostream> #include<cstdlib>#include<queue>using namespace std;int main(){    int infinity = 99999999;    int n,m;    cin>>n>>m;    int *u;    int *v;    int *w;    u = (int *)malloc((m+1)*sizeof(int));    v = (int *)malloc((m+1)*sizeof(int));    w = (int *)malloc((m+1)*sizeof(int));    int *book;    book = (int *)malloc((n+1)*sizeof(int));    for(int i = 0; i <= n; i++) book[i] = 0;    int *first;    int *next;    first = (int *)malloc((n+1)*sizeof(int));    next = (int *)malloc((m+1)*sizeof(int));    for(int i = 0; i <= n; i++) first[i] = -1;    for(int i = 1; i <= m; i++){        cin>>u[i]>>v[i]>>w[i];        next[i] = first[u[i]];//using array to achieve adjacency list        first[u[i]] = i;    }    int *dis;    dis = (int *)malloc((n+1)*sizeof(int));    for(int i = 1; i <= n; i++){        dis[i] = infinity;    }    dis[1] = 0;        queue<int> q;     q.push(1);    book[1] = 1;    while(!q.empty()){        int k = q.front();        k = first[k];        while(k != -1){            if(dis[u[k]] + w[k] < dis[v[k]]){                dis[v[k]] = dis[u[k]] + w[k];                if(book[v[k]] == 0){                    q.push(v[k]);                    book[v[k]] = 1;                }            }            k = next[k];        }        book[q.front()] = 0;         q.pop();    }        for(int i = 2; i <= n; i++){        cout<<dis[i]<<endl;    }    return 0;}



0 0
原创粉丝点击