这道题一看应该就是判环,然后就不会了QAQ...看了网上说的,只要判断是否有正环,那么循环无数次之后一定可以赚回本钱。说实话bellman_ford算法我用的不多。。这次也是懵逼了。。参考博客是kuangbin的Orz:https://www.cnblogs.com/kuangbin/archive/2012/08/17/2644807.html
正环是刚好和板子反的,注意点都在代码里了,AC代码如下:
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
const int INF=0x3f3f3f3f;
const int MAX=105;
int n,m,s;
double vv;
struct Edge
{
int u,v;
double r,c;
}e[MAX*2];//注意×2!!!
int tol;
void addedge(int u,int v,double r,double c)
{
e[tol].u=u;e[tol].v=v;e[tol].r=r;e[tol++].c=c;
}
double dis[MAX];//注意double!
bool bellman_ford(int st,double num)
{
memset(dis,0,sizeof(dis));
dis[st]=num;//注意!!!!!!
for(int k=1;k<n;k++)//n-1次
{
bool flag=false;
for(int i=0;i<tol;i++)
{
int u=e[i].u,v=e[i].v;
double r=e[i].r,c=e[i].c;
if(dis[v]<(dis[u]-c)*r) //求最大
{
flag=true;
dis[v]=(dis[u]-c)*r;
}
}
if(!flag) return true;//没有回路
}
for(int i=0;i<tol;i++)
{
int u=e[i].u,v=e[i].v;
double r=e[i].r,c=e[i].c;
if(dis[v]<(dis[u]-c)*r)
return false;//有回路
}
return true;
}
int main()
{
while(scanf("%d%d%d%lf",&n,&m,&s,&vv)==4)
{
tol=0;
int u,v;//注意区别v和vv!!!!!!!!
double r,c;//注意double!
for(int i=0;i<m;i++)
{
scanf("%d%d",&u,&v);
scanf("%lf%lf",&r,&c);
addedge(u,v,r,c);
scanf("%lf%lf",&r,&c);
addedge(v,u,r,c);
}
if(bellman_ford(s,vv)) printf("NO\n");
else printf("YES\n");
}
return 0;
}