原理bellman-ford 判环:一旦松弛n-1次后发现再松弛值会改变,则说明存在环。
代码:
#include<iostream>
#include<cstdio>
#define RPG(i,a,b) for(int i=(a);i<(b);i++)
#define ll long long
#define maxn 500
using namespace std;
int n,m,s,cnt;
double money;
int u[maxn];
int v[maxn];
double r[maxn];
double c[maxn];
double d[maxn];
bool bellman_ford()
{
RPG(i,1,n+1)
{
d[i]=0;
}
d[s]=money;
RPG(j,0,n-1)
{
bool flag=false;
RPG(i,0,cnt)
{
// printf("%d-%d-%.2f-%.2f\n",u[i],v[i],d[u[i]],d[v[i]]);
if(d[v[i]]<(d[u[i]]-c[i])*r[i] )
{
d[v[i]]=(d[u[i]]-c[i])*r[i];
flag=true;
}
}
if(!flag)
{
return false;
}
}
RPG(i,0,cnt)
{
if(d[v[i]]<(d[u[i]]-c[i])*r[i] )
{
return true;
}
}
return false;
}
int main()
{
scanf("%d%d%d%lf",&n,&m,&s,&money);
cnt=0;
RPG(i,0,m)
{
int u1,v1;
double ruv,cuv,rvu,cvu;
scanf("%d%d%lf%lf%lf%lf",&u1,&v1,&ruv,&cuv,&rvu,&cvu);
u[cnt]=u1;
v[cnt]=v1;
r[cnt]=ruv;
c[cnt]=cuv;
cnt++;
u[cnt]=v1;
v[cnt]=u1;
r[cnt]=rvu;
c[cnt]=cvu;
cnt++;
}
if(bellman_ford())
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
return 0;
}
注意点:
每松弛一次都要判断一次flag,如果值没有改变,说明走了所有的边,相对永远不增长。则直接返回false。