ACM/ICPC 之 SPFA-兑换货币(POJ1860)

 

//水题-SPFA解法
//套汇是指兑换货币后能使本金上升
//给定本金货币编号,货币间的汇率和手续费,求能否套汇成功
//Time:16Ms	Memory:200K
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;

#define MAX 105

struct Edge {
	int u, next;
	double w, c;
	Edge(){}
	Edge(int u, double w, double c, int n):u(u), w(w), c(c), next(n){}
}e[2*MAX];

int n, m, st;
double my;
int h[MAX];
double d[MAX];
bool v[MAX];

bool spfa(int x)
{
	memset(d, 0, sizeof(d));
	memset(v, 0, sizeof(v));
	queue<int> q;
	q.push(x);
	d[x] = my;	v[x] = true;
	while (!q.empty()){
		int cur = q.front();
		q.pop();	v[cur] = false;
		for (int i = h[cur]; i != -1; i = e[i].next)
		{
			int u = e[i].u;
			double w = e[i].w, c = e[i].c;
			if ((d[cur] - c) * w > d[u]){
				d[u] = (d[cur] - c) * w;
				if (u == x) return true;	//更新了源点,则套汇成功
				if (!v[u]) {
					v[u] = true;	q.push(u);
				}
			}
		}
	}
	return false;
}

int main()
{
	memset(h, -1, sizeof(h));
	scanf("%d%d%d%lf", &n, &m, &st, &my);
	for (int i = 0; i < m; i++)
	{
		int u, v;
		double w, c;
		scanf("%d%d%lf%lf", &u, &v, &w, &c);
		e[2 * i] = Edge(v, w, c, h[u]);	h[u] = 2 * i;
		scanf("%lf%lf", &w, &c);
		e[2 * i + 1] = Edge(u, w, c, h[v]);	h[v] = 2 * i + 1;
	}
	if (spfa(st)) printf("YES\n");
	else printf("NO\n");

	return 0;
}

 

posted @ 2016-06-07 09:38  文字失效  阅读(313)  评论(0编辑  收藏  举报