现在的位置: 首页 > 综合 > 正文

POJ 1860 Currency Exchange 最短路径算法的运用

2014年01月07日 ⁄ 综合 ⁄ 共 939字 ⁄ 字号 评论关闭

 

题意:有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;
}

抱歉!评论已关闭.