# Dijkstra算法，Bellman-Ford算法和BFS算法解决有向图的单源最短路径问题

``````#include <iostream>
#include <vector>
#include <queue>
#include <fstream>
using namespace std;

struct State
{
int index, weight;
State(int i, int w) :index(i), weight(w){}
bool operator<(const State& S) const
{
return weight > S.weight;
}
};
int main()
{
ifstream in("data.txt");
int n, m, s, u, v, w; //n表示图中节点个数，m表示边的条数，s表示起始节点的索引号
vector<vector<pair<int, int>>> Adj; //图的邻接表
vector<int> Cost; //保存图中每个节点到起始节点的最短路径权值
priority_queue<State> Q;
in >> n >> m >> s;
Adj.assign(n, vector<pair<int, int>>());
Cost.assign(n, -1);
for (int i = 0; i < m; i++) //用邻接表存储图的信息
{
in >> u >> v >> w;
Adj[u].push_back(pair<int, int>(v, w));
}

Q.push(State(s, 0));
while (!Q.empty())
{
State s = Q.top();
Q.pop();
if (Cost[s.index] != -1) continue;
Cost[s.index] = s.weight;
for (int i = 0; i < Adj[s.index].size(); i++)
{
pair<int, int> p = Adj[s.index][i];
if (Cost[p.first] != -1) continue;
Q.push(State(p.first, s.weight + p.second));
}
}

cout << "Result:\n";
for (int j = 0; j < n; j++)
{
if (j == s) continue;
cout << "From " << s << " to " << j << ": ";
if (Cost[j] == -1) cout << "No Path\n";
else cout << Cost[j] << endl;
}

system("pause");
return 0;
}``````

``````#include <iostream>
#include <vector>
#include <queue>
#include <fstream>
using namespace std;

int main()
{
ifstream in("data.txt");
int n, m, s, u, v, w; //n表示图中节点个数，m表示边的条数，s表示起始节点的索引号
vector<vector<pair<int, int>>> Adj; //图的邻接表
vector<int> Cost; //保存图中每个节点到起始节点的最短路径权值
queue<pair<int,int>> Q; //pair中第一个值为节点索引号，第二个值记录当前状态下本节点到源节点的路径长度
in >> n >> m >> s;
Adj.assign(n, vector<pair<int, int>>());
Cost.assign(n, INT_MAX);
for (int i = 0; i < m; i++) //用邻接表存储图的信息
{
in >> u >> v >> w;
Adj[u].push_back(pair<int, int>(v, w));
}

Q.push(pair<int, int>(s, 0));
Cost[s] = 0;
while (!Q.empty())
{
pair<int, int> p = Q.front();
Q.pop();
int i;
for (i = 0; i < Adj[p.first].size(); i++) //遍历与节点p相连的节点，同时做松弛操作
{
pair<int, int> q=Adj[p.first][i];
if (Cost[p.first] + q.second < Cost[q.first])
{
Cost[q.first] = Cost[p.first] + q.second;
Q.push(pair<int, int>(q.first, p.second + 1));
if (p.second + 1 == n) break; //此处防止当图中存在负权值的环时，在环上无限循环
}
}
if (i < Adj[p.first].size()) break;
}

cout << "Result:\n";
if (!Q.empty()) { cout << "图中存在权值为负的环！\n"; return 0; }
for (int j = 0; j < n; j++)
{
if (j == s) continue;
cout << "From " << s << " to " << j << ": ";
if (Cost[j] == INT_MAX) cout << "No Path\n";
else cout << Cost[j] << endl;
}

system("pause");
return 0;
}``````

``````#include <iostream>
#include <vector>
#include <fstream>
using namespace std;

struct Edge
{
int s, e, weight;
//Edge(int u, int v, int w) :s(u), e(v), weight(w){}
};

int main()
{
ifstream in("data.txt");
int n, m, s, u, v, w; //n表示图中节点个数，m表示边的条数，s表示起始节点的索引号
vector<Edge> Graph; //保存图的边信息
in >> n >> m >> s;
Graph.assign(m, Edge());
vector<int> dp(n, INT_MAX); //保存每个节点到源节点的路径，经过n-1轮的优化，最终dp中保存的是最短路径
dp[s] = 0;
for (int i = 0; i < m; i++) in >> Graph[i].s >> Graph[i].e >> Graph[i].weight;
bool flag;
for (int k = 1; k < n; k++)
{
flag = false;
for (int i = 0; i < m; i++)
{
Edge E = Graph[i];
if (dp[E.s] + E.weight < dp[E.e]) //松弛操作
{
dp[E.e] = dp[E.s] + E.weight;
flag = true;
}
}
if (!flag) break; //此处做了一个小的优化：如果在k的某轮循环中，没有对dp进行任何的优化，则可以直接终止循环
}
int i;
for (i = 0; i < m; i++)
{
Edge E = Graph[i];
if (dp[E.e]>dp[E.s] + E.weight) break;
}
cout << "Result:\n";
if (i < m) { cout << "图中存在权值为负的环!\n"; getchar(); return 0; }
for (int j = 0; j < n; j++)
{
if (j == s) continue;
cout << "From " << s << " to " << j << ": ";
if (dp[j] == INT_MAX) cout << "No Path!\n";
else cout << dp[j] << endl;
}
system("pause");
return 0;
}``````

原文作者：Bellman - ford算法
原文地址: https://blog.csdn.net/lrgdongnan/article/details/52329512
本文转自网络文章，转载此文章仅为分享知识，如有侵权，请联系博主进行删除。