这几天搞差分约束,里面提到Bellman_ford的三角不等式,对Bellman_ford总结一下。。。
Bellman_ford与dijkstra都是求单源多点路径长度。但dijkstra不能带有负权值。关于dijkstra参考:http://blog.csdn.net/bill_ming/article/details/7578037 所以当负权值时就用到了Bellman_ford啦。。。
参考:http://blog.sina.com.cn/s/blog_6803426101014l1v.html
摘自百度百科:http://baike.baidu.com/view/1481053.htm
假设存在最短路径的话,那么我们只要将这条最短路径沿着权值为负的环路在绕一圈,那么这条最短路径的权值就会减少了,所以不存在最短的路径,因为路径的最小值为负无穷
一般形式:
typedef struct Edge { int u,v,w; } edge[N]; bool Bellman_ford() { //第一步初始化: for(int i = 1; i <= n; i++) dis[i] = MAX; dis[s] = 0; //第二步循环求解: for(int i = 1; i < n; i++) // 除源s外 n-1个节点 for(int j = 1; j <= edgenum; j++) if(dis [ edge[j].v ] > dis[ edge[j].u ] + edge[j].w ) { dis [ edge[j].v ] = dis[ edge[j].u ] + edge[j].w; } //如果某次循环,没有更新源点到任何顶点的dis,那提前结束 for(int i = 1; i < n; i++) // 除源s外 n-1个节点 { bool flag = false; for(int j = 1; j <= edgenum; j++) if(dis [ edge[j].v ] > dis[ edge[j].u ] + edge[j].w ) { dis [ edge[j].v ] = dis[ edge[j].u ] + edge[j].w; flag = true; } if( !flag ) { break; } } //第三步:判断是否存在负环 for(int i = 1; i <= edgenum; i++) if(dis[ edge[i].v ] > dis[ edge[i].u ] + edge[i].w ) return false; return true; }
//zhaomingming 3259 Accepted 360K 204MS C++ 1558B 2012-06-03 21:32:02 #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int N = 10010; const int INF = 999999; struct Edge { int u; int v; int t; } ; Edge edge[N]; int num; int n,m,w; int dis[N] ; bool Bellman_ford() { for(int i = 1; i <= n; i ++) { dis[i] = INF; } bool flag ; for(int i = 1; i < n; i++) { flag = false; for(int j = 1; j <= num; j++) { if(dis[edge[j].v] > dis[edge[j].u] + edge[j].t) { dis[ edge[j].v ] = dis[edge[j].u] + edge[j].t; flag = true; } } if( !flag ) break; } for(int j = 1; j <= num; j++) if(dis[ edge[j].v ] > dis[edge[j].u] + edge[j].t) return true; return false; } int main() { int F,a,b,c; int tt; cin >> F; while(F--) { cin >> n >> m >> w; num = 0; memset(edge,0,sizeof(edge)); for(int i = 1; i <= m; i++) { cin >>a >> b >>c; num ++; //无向图 edge[num].t = c; edge[num].u = a; edge[num].v = b; num ++; edge[num].t = c; edge[num].u = b; edge[num].v = a; } for(int i = 1; i <= w; i++) { cin >> a >> b >> tt; edge[++num].t = -tt; edge[num].u = a; edge[num].v = b; } if( Bellman_ford() ) cout << "YES\n"; else cout << "NO"<<endl; } return 0; }