POJ 1860 bellman_ford

#include<iostream>
#include<fstream>
#include<cstdlib>

using namespace std;

//#define DEBUG

struct exchgpnt
{
	int a;
	int b;
	double rab;
	double cab;
};

static struct exchgpnt edges[100 * 2];
static int m, n, s;
static double v;
static double dst[101];

int bellman_ford(int edgenum)
{
	int i, j;
	memset(dst, 0, sizeof dst);
	dst[s] = v;
	for (i = 1; i < n; i++) /* relax edges */
	{
		for (j = 0; j < edgenum; j++)
		{
			int a, b;
			double rab, cab;
			a = edges[j].a; 
			b = edges[j].b;
			rab = edges[j].rab; 
			cab = edges[j].cab;
			if (dst[a] == 0.0)	continue;  /* 加上这句后运行时间减半 */
			if (dst[b] < (dst[a] - cab) * rab)
			{
				if (b == s) return 1; /* 存在正向回路 */
				dst[b] =  (dst[a] - cab) * rab;
			}
		}
	}
	for (j = 0; j < edgenum; j++)
	{
		int a, b;
		double rab, cab;
		a = edges[j].a; 
		b = edges[j].b;
		rab = edges[j].rab; 
		cab = edges[j].cab;
		if (dst[b] <  (dst[a] - cab) * rab)
		{
			return 1; /* 存在正向回路 */
		}
	}
	return 0;
}

int main()
{
#ifdef DEBUG
	fstream cin("G:\\book\\algorithms\\acm\\Debug\\dat.txt");
#endif
	while (cin >> n >> m >> s >> v)
	{
		int i, p;
		for (p = i = 0; i < m; i++)
		{
			int a, b;
			double rab, rba, cab, cba;
			//cin >> a >> b >> rab >> cab >> rba >> cba;
			/* 采用下面的输入方式时间减到0MS */
			scanf("%d%d%lf%lf%lf%lf", &a, &b, &rab, &cab, &rba, &cba);
			edges[p].a = a; edges[p].b = b;
			edges[p].cab = cab, edges[p++].rab = rab;

			edges[p].a = b; edges[p].b = a;
			edges[p].cab = cba, edges[p++].rab = rba;
		}
		if (bellman_ford(p))
			printf("YES\n");
		else
			printf("NO\n");
	}

	return 0;
}

n种货币看成n个顶点,货币之间的转换就是顶点之间的边。这样输入数据就构成了一张图,问在图中是否存在从s------>s的正权回路。

就是s货币经过若干次兑换之后再换回s货币,数量会增加。基本思想和最短路径中的bellman_ford算法相同。bellman_ford算法以边

为输入。通过对全部的边做Relax操作n-1次,如果图中不存在负权回路,就能够得到从源点s到其他节点的最短路径的值。如果存在负

权回路,可以发现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值