hdoj_2544----Bellman_Ford+队列

#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;
}

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