这几天搞差分约束,里面提到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;
}