這道題一看應該就是判環,然後就不會了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;
}