题意:有N种货币 M个交换点,每个交换点提供 a,b两种货币的交换 汇率为rate 手续费为commission;假设你持有一种货币(S) 面值V;
让你去交换其他货币,如果你能找到一个交换路径 使得你的钱一直在增加 则输出YES 否则 输出NO;
思路:设货币 为 点, 交换点为 边; (现有货币-手续费) *汇率 为边的关系函数;题意即求 最长路径 判断 图 是否存在 正权回路;
逆 利用 bellman 算法 :http://blog.csdn.net/jun_sky/article/details/7014446
#include <iostream>
using namespace std;
const int M = 105;
double dis[M];
int m,n,s;
double v;
struct Edge
{
int a,b;
double r,c;
}e[M*2];
bool bellman_ford()
{
int i,j;
memset(dis, 0, sizeof(dis));
dis[s] = v;
for(i=1; i<n; i++)
{
bool flag = false;
for(j=1; j<=2*m; j++)
{
if(dis[e[j].b] < (dis[e[j].a]-e[j].c)*e[j].r)
{
dis[e[j].b] = (dis[e[j].a]-e[j].c)*e[j].r;
flag = true;
}
}
if(!flag) break;
}
for(i=1; i<=2*m; i++)
{
if(dis[e[i].b] < (dis[e[i].a]-e[i].c)*e[i].r)
return true;
}
return false;
}
int main()
{
int i;
scanf("%d %d %d %lf", &n, &m, &s, &v);
for(i=1; i<=m; i++)
{
scanf("%d %d", &e[i].a, &e[i].b);
scanf("%lf %lf", &e[i].r, &e[i].c);
e[i+m].a = e[i].b; e[i+m].b=e[i].a;
scanf("%lf %lf", &e[i+m].r, &e[i+m].c);
}
if(bellman_ford())
printf("YES\n");
else
printf("NO\n");
return 0;
}