poj 1860 2378 3259带负边最短路 ** bellman ford 模板
2013-03-26 16:49
477 查看
题意很明确了
采用FIFO的基本队列进行bellman ford计算
整理一下 bellman ford 模板如下 针对 poj 2387使用
同样的方式,针对poj 1860 货币交换 进行应用
注意到 修改的地方是
Edge的定义 以及松弛的规则(因为现在是判断正环的存在性)
用同样的方法解poj 3259 时光穿梭
采用FIFO的基本队列进行bellman ford计算
#include <iostream> #include <vector> #include <map> #include <list> #include <set> #include <deque> #include <stack> #include <queue> #include <algorithm> #include <cmath> #include <cctype> #include <cstdio> #include <iomanip> #include <cmath> #include <cstdio> #include <iostream> #include <string> #include <sstream> #include <cstring> #include <queue> using namespace std; ///宏定义 const int INF = 10000000; const int MAXN = 1257; const int maxn = MAXN; ///全局变量 和 函数 /// struct Edge { int from, to; double R, C; }; vector<Edge> edges; //边列表 vector<int> G[maxn]; //每个结点出发的边编号 //bool done[maxn]; //是否已永久编号 double d[maxn]; //s到各个点的距离 int N, M, S; double V; bool bellman_ford() { queue<int> q; bool inq[maxn]; int cnt[maxn]; memset(cnt, 0, sizeof(cnt)); memset(inq, false, sizeof(inq)); memset(d, 0, sizeof(d)); d[S] = V; q.push(S); while(!q.empty()) { int cur = q.front(); q.pop(); inq[cur] = false; bool flag = false; for(int i = 0; i < G[cur].size(); i++) { Edge &e = edges[ G[cur][i] ]; if (d[e.to] < (d[cur] - e.C) * e.R) { flag = true; d[e.to] = (d[cur] - e.C) * e.R; if(!inq[e.to]) { inq[e.to] = true; q.push(e.to); if(++cnt[e.to] > N) return true; } } } } return false; } int main() { ///变量定义 int i, j; while(cin >> N >> M >> S >> V) { for(i = 0; i <= N; i++) { G[i].clear(); } edges.clear(); for(i = 0; i < M; i++) { int from, to; double R, C, R1, C1; cin >> from >> to >> R >> C >> R1 >> C1; Edge tmp; tmp.from = from; tmp.to = to; tmp.R = R; tmp.C = C; edges.push_back(tmp); int m = edges.size(); G[from].push_back(m - 1); tmp.from = to; tmp.to = from; tmp.R = R1; tmp.C = C1; edges.push_back(tmp); m = edges.size(); G[to].push_back(m - 1); } if(bellman_ford()) cout << "YES" << endl; else cout << "NO" << endl; } ///结束 return 0; }
整理一下 bellman ford 模板如下 针对 poj 2387使用
#include <iostream> #include <vector> #include <map> #include <list> #include <set> #include <deque> #include <stack> #include <queue> #include <algorithm> #include <cmath> #include <cctype> #include <cstdio> #include <iomanip> #include <cmath> #include <cstdio> #include <iostream> #include <string> #include <sstream> #include <cstring> #include <queue> using namespace std; ///宏定义 const int INF = 10000000; const int MAXN = 1257; const int maxn = MAXN; ///全局变量 和 函数 /// struct Edge { int from, to, dist; }; struct BellmanFord { int n, m; 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) { Edge edge; edge.from = from; edge.to = to; edge.dist = dist; edges.push_back(edge); m = edges.size(); G[from].push_back(m - 1); } bool negativeCycle(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[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 true; } } } } return false; } }; int t, n; //int N, M, S, V; int main() { ///变量定义 int i, j; while(scanf("%d %d", &t, &n) != EOF) { BellmanFord bellman_ford; bellman_ford.init(n); for(i = 0; i < t; i++) { int from, to, weight; scanf("%d %d %d", &from, &to, &weight); bellman_ford.AddEdge(from, to, weight); bellman_ford.AddEdge(to, from, weight); } bellman_ford.negativeCycle(n); int ans = bellman_ford.d[1]; printf("%d\n", ans); } ///结束 return 0; }
同样的方式,针对poj 1860 货币交换 进行应用
注意到 修改的地方是
Edge的定义 以及松弛的规则(因为现在是判断正环的存在性)
#include <iostream> #include <vector> #include <map> #include <list> #include <set> #include <deque> #include <stack> #include <queue> #include <algorithm> #include <cmath> #include <cctype> #include <cstdio> #include <iomanip> #include <cmath> #include <cstdio> #include <iostream> #include <string> #include <sstream> #include <cstring> #include <queue> using namespace std; ///宏定义 const int INF = 10000000; const int MAXN = 1257; const int maxn = MAXN; ///全局变量 和 函数 /// int N, M, S; double V; struct Edge { // int from, to, dist; //根据题意修改结构体,上面的是原来的定义 int from, to; double R, C; }; struct BellmanFord { int n, m; vector<Edge> edges; //边的存储 vector<int> G[maxn]; //点的邻接表 bool inq[maxn]; //是否在队列中 // int d[maxn]; //源点到各点的距离 double d[maxn]; //根据题意采用double类型 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) { Edge edge; edge.from = from; edge.to = to; edge.dist = dist; edges.push_back(edge); m = edges.size(); G[from].push_back(m - 1); }*/ //可对比原始的定义 void AddEdge(int from, int to, double R, double C) { Edge edge; edge.from = from; edge.to = to; edge.R = R; edge.C = C; edges.push_back(edge); m = edges.size(); G[from].push_back(m - 1); } bool negativeCycle(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; //根据题意修改为0 d[i] = 0; } d[s] = V; //根据题意为初始钱数 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[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 true; } }*/ if(d[e.to] < (d[u] - e.C) * e.R ) { d[e.to] = (d[u] - e.C) * e.R; // p[e.to] = G[u][i]; if(!inq[e.to]) { Q.push(e.to); inq[e.to] = true; if(++cnt[e.to] > n) return true; //存在正环 } } } } return false; } }; int main() { ///变量定义 int i, j; while(cin >> N >> M >> S >> V) { BellmanFord bellman_ford; bellman_ford.init(N); for(i = 0; i < M; i++) { int from, to; double R, C, R1, C1; cin >> from >> to >> R >> C >> R1 >> C1; bellman_ford.AddEdge(from, to, R, C); bellman_ford.AddEdge(to, from, R1, C1); } if (bellman_ford.negativeCycle(S)) cout << "YES" << endl; else cout << "NO" << endl; } ///结束 return 0; }
用同样的方法解poj 3259 时光穿梭
#include <iostream> #include <vector> #include <map> #include <list> #include <set> #include <deque> #include <stack> #include <queue> #include <algorithm> #include <cmath> #include <cctype> #include <cstdio> #include <iomanip> #include <cmath> #include <cstdio> #include <iostream> #include <string> #include <sstream> #include <cstring> #include <queue> using namespace std; ///宏定义 const int INF = 10000000; const int MAXN = 1257; const int maxn = MAXN; ///全局变量 和 函数 /// struct Edge { int from, to, dist; }; struct BellmanFord { int n, m; 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) { Edge edge; edge.from = from; edge.to = to; edge.dist = dist; edges.push_back(edge); m = edges.size(); G[from].push_back(m - 1); } bool negativeCycle(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; //根据题意修改为0 } 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[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 true; } } } } return false; } }; int T; int N, M, W; int main() { ///变量定义 int i, j; cin >> T; while (T--) { cin >> N >> M >> W; BellmanFord bellman_ford; bellman_ford.init(N); for (i = 0; i < M; i++) { int S, E, T; cin >> S >> E >> T; bellman_ford.AddEdge(S, E, T); bellman_ford.AddEdge(E, S, T); } for (i = 0; i < W; i++) { int S, E, T; cin >> S >> E >> T; bellman_ford.AddEdge(S, E, -T); } if (bellman_ford.negativeCycle(1)) { cout << "YES" << endl; } else cout << "NO" << endl; } ///结束 return 0; }
相关文章推荐
- Wormholes( POJ 3259)(Bellman-Ford+SPFA)(判断是否有负权环)(最短路模板)
- poj 3259 虫洞 & poj 1860 货币兑换 bellman-ford解法
- 最短路(Bellman_Ford) POJ 1860 Currency Exchange
- POJ 1860 Currency Exchange(最短路 Bellman-Ford)
- poj 1860 Currency Exchange (最短路bellman_ford思想找正权环 最长路)
- POJ 3259 Wormholes (图论---最短路 Bellman-Ford || SPFA)
- POJ1860--Currency Exchange(最短路Bellman_Ford)
- 带负权的最短路bellman_ford——POJ 3259 Wormholes题解
- POJ1860 Currency Exchange 最短路bellman-ford
- poj 3259 Wormholes 最短路(Bellman_Ford)
- Currency Exchange POJ - 1860 单源最短路 Bellman_Ford
- POJ 3259-Wormholes (Bellman-Ford&&SPFA) (模板题)
- Currency Exchange POJ - 1860 Bellman-Ford最短路
- 最短路(Bellman_Ford) POJ 3259 Wormholes
- poj - 3259 Wormholes (bellman-ford算法求最短路)
- bellman_ford算法模板 (poj 3259)
- POJ 3259 Wormholes(最短路Bellman_Ford)
- Wormholes POJ - 3259 最短路之找负圈(Bellman-Ford)
- POJ 3259 Wormholes (Bellman-ford)
- poj 1860 最短路—Bellman-Ford算法