Bellman-Ford算法
以下操作循环执行至多n-1次,n为顶点数:
对于每一条边e(u, v),如果Distant[u] + w(u, v) < Distant[v],则另Distant[v] = Distant[u]+w(u, v)。w(u, v)为边e(u,v)的权值;
若上述操作没有对Distant进行更新,说明最短路径已经查找完毕,或者部分点不可达,跳出循环。否则执行下次循环;
用其求是否存在正环:bellman-ford算法 n-1次循环,循环内部比较d[u]和d[v]+weight[v][u]的大小,值在n-1次循环中出现不更新,说明无正环,当循环之后,再次判断d[u]和d[v]+weight[v][u]的大小,发现后者依然会增大,那么说明正环存在
#include <iostream>
#define MAXN 110
#define MAXE 210
using namespace std;
double dist[MAXN];
int VU[MAXE][2];
double RC[MAXE][2];
int tol=0;
bool bellman_ford(int start,int n,double value){
for(int i=1;i<=n;i++) dist[i]=0;
dist[start]=value;
for(int i=1;i<n;i++){
bool flag=0;
for(int j=0;j<tol;j++){
int v=VU[j][0];
int u=VU[j][1];
if(dist[u]<(dist[v]-RC[j][1])*RC[j][0]){
flag=1;
dist[u]=(dist[v]-RC[j][1])*RC[j][0];
}
}
if(!flag) return false;//无正环,即一次循环无增长
}
for(int j=0;j<tol;j++){
if(dist[VU[j][1]]<(dist[VU[j][0]]-RC[j][1])*RC[j][0])
return true;
}
return false;
}
int main(){
int N,M,S;
int v,u;
double V,rab,cab,rba,cba;
while(cin>>N>>M>>S>>V){
tol=0;
while(M--){
cin>>v>>u>>rab>>cab>>rba>>cba;
VU[tol][0]=v;
VU[tol][1]=u;
RC[tol][0]=rab;
RC[tol][1]=cab;
tol++;
VU[tol][0]=u;
VU[tol][1]=v;
RC[tol][0]=rba;
RC[tol][1]=cba;
tol++;
}
if(bellman_ford(S,N,V)){
cout<<"YES"<<endl;
}else{
cout<<"NO"<<endl;
}
}
}