单点最短路径算法 bellman-ford模板和队列优化后的spfa算法模板

来源:互联网 发布:顶速网络机顶盒 编辑:程序博客网 时间:2024/05/22 03:59

朴素的bellman-ford算法,直接见代码:

/** About:  Bellman-Ford算法* Author: Tanky Woo* Blog:   www.WuTianqi.com*/ #include <iostream>using namespace std;const int maxnum = 100;const int maxint = 99999; // 边,typedef struct Edge{    int u, v;    // 起点,重点    int weight;  // 边的权值}Edge; Edge edge[maxnum];     // 保存边的值int  dist[maxnum];     // 结点到源点最小距离 int nodenum, edgenum, source;    // 结点数,边数,源点 // 初始化图void init(){    // 输入结点数,边数,源点    cin >> nodenum >> edgenum >> source;    for(int i=1; i<=nodenum; ++i)        dist[i] = maxint;    dist[source] = 0;    for(int i=1; i<=edgenum; ++i)    {        cin >> edge[i].u >> edge[i].v >> edge[i].weight;        if(edge[i].u == source)          //注意这里设置初始情况            dist[edge[i].v] = edge[i].weight;    }} // 松弛计算void relax(int u, int v, int weight){    if(dist[v] > dist[u] + weight)        dist[v] = dist[u] + weight;} bool Bellman_Ford(){    for(int i=1; i<=nodenum-1; ++i)        for(int j=1; j<=edgenum; ++j)            relax(edge[j].u, edge[j].v, edge[j].weight);    bool flag = 1;    // 判断是否有负环路    for(int i=1; i<=edgenum; ++i)        if(dist[edge[i].v] > dist[edge[i].u] + edge[i].weight)        {            flag = 0;            break;        }    return flag;}int main(){    //freopen("input3.txt", "r", stdin);    init();    if(Bellman_Ford())        for(int i = 1 ;i <= nodenum; i++)            cout << dist[i] << endl;    return 0;}


队列优化的(spfa算法)l邻接表实现:

用队列记录修改了距离的点,u->v,枚举u的所有边,如果松弛了点v,并且v不在队列中,加入队列,如果没有负劝边,那么必然会在一段操作后,队列为空,则停止;

如果有负劝边那么不会停止,所以要判断是否有负劝边,方法是当一个点进入队列的次数超过n(顶点数),则说明有负劝边,代码如下

#include<iostream>#include<cstdio>#include<vector>#include<cstring>#include<queue>using namespace std;const int MAXN=100;int inf=1<<30; vector<int> map[MAXN]; //图的邻接表vector<int> w[MAXN];//每条边的权值,如果是稀疏图则这样存储,否则可以直接用map[x][y]int count[MAXN];//判断负环,记录进入队列的次数,如果超过n次就一定有负环 int main(){//n为顶点数,m为边数 int n,m,x,y,z;int dis[MAXN]={0};bool inqueue[MAXN]={0};memset(count,0,sizeof(count));scanf("%d%d",&n,&m);for (int i=1;i<=n;i++)dis[i]=inf;dis[1]=0;for (int i=0;i<m;i++){scanf("%d%d%d",&x,&y,&z);map[x].push_back(y);w[x].push_back(z);//记录权值 }queue<int> q;q.push(1);inqueue[1]=1;count[1]++; int v,u,t; bool flag=1;while(!q.empty()&&flag){u=q.front();q.pop();inqueue[u]=0;for (int i=0;i<map[u].size();i++){v=map[u][i];t=w[u][i];if (dis[v]>dis[u]+t){dis[v]=dis[u]+t;if (!inqueue[v]){q.push(v);inqueue[v]=1;count[v]++;if (count[v]>n) flag=0;}}}for (int i=1;i<=n;i++) printf("%d ",dis[i]); printf("\n"); }if (flag==0) printf("false!\n");} 




0 0
原创粉丝点击