#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;
const int INF = 1e9;
const int maxn = 1000;
int E;
struct Edge{
int from, to, dist;
Edge(int u = 0, int v = 0, int d = 0):from(u), to(v), dist(d) {}
};
struct Bellman_ford {
int n, m;// n是点的个数
vector<Edge> edges; //存储路径
vector<int> G[maxn]; //存储编号
bool inq[maxn]; //是否走过访问标记
int d[maxn]; //最小权值
int p[maxn]; //当前点的上一个点
int cnt[maxn]; //统计每个边的编号所对应的点松弛操作次数
void init(int n) { //初始化
this->n = n;
for(int i = 0; i <= n; i++) G[i].clear();
edges.clear();
}
void AddEdge(int from, int to, int dist) { //添加路径:起点,终点,路费
edges.push_back(Edge(from, to, dist)); //添加好路径
m = edges.size(); //获取该路径的编号
G[from].push_back(m-1); //保存这个编号到编号数组中
}
bool bellman_ford(int s) {
queue<int> Q; //申请一个普通队列
memset(inq, 0, sizeof(inq)); //初始化访问标记
memset(cnt, 0, sizeof(cnt)); //初始化统计数组
for(int i = 0; i <= n; i++) d[i] = INF; //初始化每个节点的最小权值
d[s] = 0; // 更新起点的最小权值
inq[s] = true; // 起点的访问标记更新
Q.push(s); //将起点加入队列中
while(!Q.empty()) {
int u = Q.front(); Q.pop(); //取出一个点
inq[u] = false;
for(int i = 0; i < G[u].size(); i++) { //找到这个点的所有可到达点
Edge& e = edges[G[u][i]]; //获取它们的权值
if(d[u] < INF && d[e.to] > d[u]+e.dist) { //松弛操作 更新权值
d[e.to] = d[u] + e.dist;
p[e.to] = G[u][i];
if(!inq[e.to]) { //如果是没有走过的点,入队、标记、统计、
Q.push(e.to);
inq[e.to] = true;
if(++cnt[e.to] > n) return false;
}
}
}
}
return true;
}
};
int main() {
int N;
Bellman_ford temp;
while(cin >> E >> N && E && N) {
temp.init(E);
int f, t, d;
for(int i = 0; i < N; i++) {
cin >> f >> t >> d;
temp.AddEdge(f, t, d);
temp.AddEdge(t, f, d);
}
temp.bellman_ford(1);
cout << temp.d[E] << endl;
}
return 0;
}
hdoj_2544----Bellman_Ford+队列
原文作者:Bellman - ford算法
原文地址: https://blog.csdn.net/czkct/article/details/50802186
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/czkct/article/details/50802186
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。