题目大意:小明有一种Currency,可以换成其它的再换回来,换的时候要交一点commission,问最后他的钱会不会变多。
思路:首先必然是要有环的,然后这个环应该是转一圈下来是正的(正常的为负),恰好和Bellman-Ford负环情况相反,那我们把松弛操作反过来就可以用了。(正常情况是不应该增长的,我们换个角度,把代价看做正的,那么赚的话就对应负环了,于是是求最短路,短到负就更好了)
注意:1.精度,开始用float,WA,后来用double,AC。
2.用邻接表,因为两Currency间可能不止一条边。
//Bellman-Ford
#include<cstdio>
#include<cstdlib>
#define M 100
#define N 101
class Node
{
public:
int v;
double dis;
double c;
Node *nptr;
Node()
{
v=0;
dis = 0;
c = 0;
nptr = NULL;
}
Node(int a, double b, double c , Node *p)
{
v=a;
dis = b;
this->c = c;
nptr = p;
}
};
Node *g[N];
double d[N];
int m;
int n,s;
double v;
void empty()
{
int i;
for(i=1;i<N;i++)
{
Node *temp, *del;
temp = g[i];
g[i] = NULL;
while(temp != NULL)
{
del = temp;
temp = temp->nptr;
delete del;
}
}
for(i=1;i<N;i++)
{
d[i] = 0;
}
}
void ini()
{
int i;
double ra,ca,rb,cb;
int a,b;
Node *ins;
empty();
scanf("%d%d%d%lf",&n,&m,&s,&v);
d[s] = v;
for(i=0;i<m;i++)
{
scanf("%d%d%lf%lf%lf%lf",&a,&b,&ra,&ca,&rb,&cb);
ins = new Node(b,ra,ca,g[a]);
g[a] = ins;
ins = new Node(a,rb,cb,g[b]);
g[b] = ins;
}
}
bool relax_all()
{
bool flag = false;
Node *visit;
for(int i=1; i<=n; i++)
{
visit = g[i];
while(visit != NULL)
{
if(d[i] > visit->c && d[visit->v] < (d[i] - visit->c) * visit->dis)
{
flag = true;
d[visit->v] = (d[i] - visit->c) * visit->dis;
}
visit = visit->nptr;
}
}
return flag;
}
bool Bellman_Ford()
{
int i;
// printf("%lf",v);
for(i=1;i<=n;i++)
{
if(!relax_all())
return true;
}
return false;
}
int main()
{
// freopen("test.txt","r",stdin);
ini();
if(Bellman_Ford())
printf("NO");
else
printf("YES");
// system("PAUSE");
return 0;
}