(模板)解决带负权最短路径 Bellman-ford 与 SPFA(前者的队列优化)
// 模板记录
// Bellman-ford O(V*E) s到每个点的最短路
1 #include<cstdio> 2 #define INF 0x3f3f3f3f 3 const int MAXN = 100+5; 4 const int MAXM = 10000+5; 5 6 struct node { 7 int u, v, w; 8 } edge[MAXM]; 9 10 int n, m, x;// 点的数量,边的数量,源点 11 int dis[MAXN]; 12 13 bool Bellman_ford() { 14 for(int i = 0; i < n-1; ++i) { 15 for(int j = 0; j != m; ++j) { 16 if(dis[edge[j].v] > dis[edge[j].u] + edge[j].w) { 17 dis[edge[j].v] = dis[edge[j].u] + edge[j].w; 18 } 19 } 20 } 21 bool flag = true; 22 for(int i = 0; i != m; ++i) { 23 if(dis[edge[i].v] > dis[edge[i].u] + edge[i].w) { 24 flag = false; 25 break; 26 } 27 } 28 return flag; 29 } 30 31 int main() { 32 cin >> n >> m >> x; 33 for(int i = 1; i <= n; ++i) dis[i] = INF; 34 dis[x] = 0; 35 for(int i = 0; i != m; ++i) { 36 cin >> edge[i].u >> edge[i].v >> edge[i].w; 37 if(edge[i].u == x) { 38 dis[edge[i].v] = edge[i].w; 39 } 40 } 41 if(Bellmam_ford()) cout << "have minimun road\n"; 42 else cout << "not have minimun road\n"; 43 return 0; 44 }
// poj 1860 Bellman-ford
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 * @Promlem: 3 * @Time Limit: ms 4 * @Memory Limit: k 5 * @Author: pupil-XJ 6 * @Date: 2019-10-25 16:51:13 7 * @LastEditTime: 2019-10-25 20:25:55 8 */ 9 #include<cstdio> 10 #include<cstring> 11 #include<cmath> 12 #include<iostream> 13 #include<string> 14 #include<algorithm> 15 #include<iomanip> 16 #include<vector> 17 #include<queue> 18 #include<stack> 19 #include<set> 20 #include<map> 21 #define read(n) n = read_n() 22 #define rep(i, n) for(int i=0;i!=n;++i) 23 #define per(i, n) for(int i=n-1;i>=0;--i) 24 #define Rep(i, sta, n) for(int i=sta;i!=n;++i) 25 #define rep1(i, n) for(int i=1;i<=n;++i) 26 #define per1(i, n) for(int i=n;i>=1;--i) 27 #define Rep1(i, sta, n) for(int i=sta;i<=n;++i) 28 #define L k<<1 29 #define R k<<1|1 30 #define mid (tree[k].l+tree[k].r)>>1 31 #define eps 1e-10 32 using namespace std; 33 const int INF = 0x3f3f3f3f; 34 typedef long long ll; 35 36 inline int read_n() { 37 char c=getchar();int x=0,f=1; 38 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 39 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 40 return x*f; 41 } 42 // ----------------------------------------------------- 43 const int MAXN = 100+5; 44 const int MAXM = 200+5; 45 46 int n, m, m2, x; 47 double sta; 48 49 struct node { 50 int u, v; 51 double r, c; 52 } edge[MAXM]; 53 54 double dis[MAXN]; 55 56 bool Bellman_ford() { 57 bool flag; 58 rep(i, n-1) { 59 flag = false; 60 rep(j, m) { 61 if(dis[edge[j].v] < (dis[edge[j].u]-edge[j].c)*edge[j].r) { 62 dis[edge[j].v] = (dis[edge[j].u]-edge[j].c)*edge[j].r; 63 flag = true; 64 } 65 } 66 if(!flag) break; 67 } 68 flag = false; 69 rep(i, m) { 70 if(dis[edge[i].v] < (dis[edge[i].u]-edge[i].c)*edge[i].r) { 71 return true; 72 } 73 } 74 return false; 75 } 76 77 int main() { 78 ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); 79 cin >> n >> m2 >> x >> sta; 80 m = 0; 81 rep(i, m2) { 82 cin >> edge[m].u >> edge[m].v; 83 cin >> edge[m].r >> edge[m].c; 84 ++m; 85 edge[m].u = edge[m-1].v; 86 edge[m].v = edge[m-1].u; 87 cin >> edge[m].r >> edge[m].c; 88 ++m; 89 } 90 rep1(i, n) dis[i] = 0; 91 dis[x] = sta; 92 if(Bellman_ford()) cout << "YES\n"; 93 else cout << "NO\n"; 94 return 0; 95 }
// SPFA O(k*E)k为平均入队列次数,稀疏图通常小于2。s到每个点的最短路
1 #include<iostream> 2 #include<queue> 3 using namespace std; 4 #define INF 0x3f3f3f3f 5 const int MAXN = 100+5; 6 const int MAXM = 1000+5; 7 8 int num; 9 int head[MAXN]; 10 struct node {// 链式向前星 11 int v, next; 12 int w; 13 } edge[MAXM]; 14 15 inline void add(int x, int y, int w) { 16 edge[num].v = y; 17 edge[num].next = head[x]; 18 edge[num].w = w; 19 head[x] = num++; 20 } 21 22 int n, m; 23 int dis[MAXN], vis[MAXN], inq[MAXN]; 24 25 bool SPFA(int s) { 26 queue<int> q; 27 for(int i = 1; i <= n; ++i) { 28 dis[i] = INF; 29 vis[i] = inq[i] = 0; 30 } 31 dis[i] = 0; 32 vis[s] = inq[s] = 1; 33 q.push(s); 34 while(!q.empty()) { 35 int u = q.front(); 36 u.pop(); 37 vis[u] = 0; 38 for(int i = head[x]; i != -1; i = edge[i].next) { 39 int v = edge[i].v; 40 if(dis[v] > dis[u] + edge[i].w) { 41 dis[v] = dis[u] + edge[i].w; 42 if(!vis[v]) { 43 q.push(v); 44 vis[v] = 1; 45 ++inq[v]; 46 if(inq[v] > n) return false; 47 } 48 } 49 } 50 } 51 return true; 52 } 53 54 int main() { 55 cin >> n >> m; 56 int s, e, v; 57 num = 0; 58 for(int i = 1; i <= n; ++i) head[i] = -1; 59 for(int i = 0; i != m; ++i) { 60 cin >> s >> e >> v; 61 add(s, e, v); 62 } 63 SPFA(1); 64 return 0; 65 }
// poj 3259
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 * @Promlem: 3 * @Time Limit: ms 4 * @Memory Limit: k 5 * @Author: pupil-XJ 6 * @Date: 2019-10-26 00:52:36 7 * @LastEditTime: 2019-10-26 01:40:33 8 */ 9 #include<cstdio> 10 #include<cstring> 11 #include<cmath> 12 #include<iostream> 13 #include<string> 14 #include<algorithm> 15 #include<iomanip> 16 #include<vector> 17 #include<queue> 18 #include<stack> 19 #include<set> 20 #include<map> 21 #define read(n) n = read_n() 22 #define rep(i, n) for(int i=0;i!=n;++i) 23 #define per(i, n) for(int i=n-1;i>=0;--i) 24 #define Rep(i, sta, n) for(int i=sta;i!=n;++i) 25 #define rep1(i, n) for(int i=1;i<=n;++i) 26 #define per1(i, n) for(int i=n;i>=1;--i) 27 #define Rep1(i, sta, n) for(int i=sta;i<=n;++i) 28 #define L k<<1 29 #define R k<<1|1 30 #define mid (tree[k].l+tree[k].r)>>1 31 #define eps 1e-10 32 using namespace std; 33 const int INF = 0x3f3f3f3f; 34 typedef long long ll; 35 36 inline int read_n() { 37 char c=getchar();int x=0,f=1; 38 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 39 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 40 return x*f; 41 } 42 // ----------------------------------------------------- 43 const int MAXN = 500+5; 44 const int MAXM = 5200+5; 45 46 int n, m1, m2; 47 48 int num; 49 struct node { 50 int v, next; 51 int w; 52 } edge[MAXM]; 53 54 int head[MAXN]; 55 inline void add(int x, int y, int w) { 56 edge[num].v = y; 57 edge[num].next = head[x]; 58 edge[num].w = w; 59 head[x] = num++; 60 } 61 62 int dis[MAXN], vis[MAXN], inq[MAXN]; 63 64 bool SPFA(int s) { 65 queue<int> q; 66 rep1(i, n) { 67 dis[i] = INF; 68 vis[i] = inq[i] = 0; 69 } 70 dis[s] = 0; 71 vis[s] = inq[s] = 1; 72 q.push(s); 73 while(!q.empty()) { 74 int u = q.front(); 75 q.pop(); 76 vis[u] = 0; 77 for(int i = head[u]; i != -1; i = edge[i].next) { 78 int v = edge[i].v; 79 if(dis[v] > dis[u] + edge[i].w) { 80 dis[v] = dis[u] + edge[i].w; 81 if(!vis[v]) { 82 q.push(v); 83 vis[v] = 1; 84 ++inq[v]; 85 if(inq[v] > n) return true; 86 } 87 } 88 } 89 } 90 return false; 91 } 92 93 int main() { 94 //ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); 95 int T = read_n(); 96 int s, e, v; 97 while(T--) { 98 read(n); read(m1); read(m2); 99 rep1(i, n) head[i] = -1; 100 num = 0; 101 rep(i, m1) { 102 read(s); read(e); read(v); 103 add(s, e, v); 104 add(e, s, v); 105 } 106 rep(i, m2) { 107 read(s); read(e); read(v); 108 add(s, e, -v); 109 } 110 if(SPFA(1)) cout << "YES\n"; 111 else cout << "NO\n"; 112 } 113 return 0; 114 }