1 /*
2 最短路(Bellman_Ford):求负环的思路,但是反过来用,即找正环
3 详细解释:http://blog.csdn.net/lyy289065406/article/details/6645778
4 */
5 #include <cstdio>
6 #include <iostream>
7 #include <algorithm>
8 #include <cstring>
9 #include <vector>
10 #include <cmath>
11 #include <queue>
12 #include <map>
13 #include <set>
14 using namespace std;
15
16 const int MAXN = 100 + 10;
17 const int INF = 0x3f3f3f3f;
18 const double EPS = 1e-8;
19 struct NODE
20 {
21 int u, v;
22 double r, c;
23 }node[MAXN*2];
24 double d[MAXN];
25
26 bool Bellman_Ford(int s, int n, int tot, double V)
27 {
28 memset (d, 0, sizeof (d));
29 d[s] = V;
30 bool flag;
31 for (int i=1; i<=n-1; ++i)
32 {
33 flag = false;
34 for (int j=1; j<=tot; ++j)
35 {
36 NODE e = node[j];
37 if (d[e.v] < (d[e.u] - e.c) * e.r)
38 {
39 d[e.v] = (d[e.u] - e.c) * e.r; flag = true;
40 }
41 }
42 if (!flag) break;
43 }
44
45 for (int i=1; i<=tot; ++i)
46 {
47 NODE e = node[i];
48 if (d[e.v] < (d[e.u] - e.c) * e.r) return true;
49 }
50
51 return false;
52 }
53
54 int main(void) //POJ 1860 Currency Exchange
55 {
56 //freopen ("A.in", "r", stdin);
57
58 int n, m, s;
59 double V;
60 while (~scanf ("%d%d%d%lf", &n, &m, &s, &V))
61 {
62 int tot = 0;
63 for (int i=1; i<=m; ++i)
64 {
65 int x, y;
66 double rab, cab, rba, cba;
67 scanf ("%d%d%lf%lf%lf%lf", &x, &y, &rab, &cab, &rba, &cba);
68 //printf ("%d %d %lf %lf %lf %lf
", x, y, rab, cab, rba, cba);
69 node[++tot].u = x; node[tot].v = y;
70 node[tot].r = rab; node[tot].c = cab;
71 node[++tot].u = y; node[tot].v = x;
72 node[tot].r = rba; node[tot].c = cba;
73 }
74
75 if (Bellman_Ford (s, n, tot, V)) puts ("YES");
76 else puts ("NO");
77 }
78
79 return 0;
80 }
SPFA重写一遍
#include <cstdio> #include <algorithm> #include <cstring> #include <queue> using namespace std; const int N = 100 + 10; struct Edge { int v, nex; double r, c; Edge() {} Edge(int v, double r, double c, int nex) : v (v), r (r), c (c), nex (nex) {} }edge[N*2]; int head[N]; double d[N]; bool vis[N]; int cnt[N]; int n, m, e; double val; void init(void) { memset (head, -1, sizeof (head)); e = 0; } void add_edge(int u, int v, double r, double c) { edge[e] = Edge (v, r, c, head[u]); head[u] = e++; } bool SPFA(int s) { memset (vis, false, sizeof (vis)); memset (d, 0, sizeof (d)); memset (cnt, 0, sizeof (cnt)); d[s] = val; cnt[s] = 0; vis[s] = true; queue<int> que; que.push (s); while (!que.empty ()) { int u = que.front (); que.pop (); vis[u] = false; for (int i=head[u]; ~i; i=edge[i].nex) { int v = edge[i].v; double r = edge[i].r, c = edge[i].c; if (d[v] < (d[u] - c) * r) { d[v] = (d[u] - c) * r; if (!vis[v]) { vis[v] = true; que.push (v); if (++cnt[v] > n) return true; } } } } return false; } int main(void) { int s; while (scanf ("%d%d%d%lf", &n, &m, &s, &val) == 4) { init (); for (int i=1; i<=m; ++i) { int u, v; double r1, c1, r2, c2; scanf ("%d%d%lf%lf%lf%lf", &u, &v, &r1, &c1, &r2, &c2); add_edge (u, v, r1, c1); add_edge (v, u, r2, c2); } if (SPFA (s)) puts ("YES"); else puts ("NO"); } return 0; }