E - Currency Exchange POJ-1860(spfa算法的应用)

E - Currency Exchange

Several currency exchange points are working in our city. Let us suppose that each point specializes in two particular currencies and performs exchange operations only with these currencies. There can be several points specializing in the same pair of currencies. Each point has its own exchange rates, exchange rate of A to B is the quantity of B you get for 1A. Also each exchange point has some commission, the sum you have to pay for your exchange operation. Commission is always collected in source currency.
For example, if you want to exchange 100 US Dollars into Russian Rubles at the exchange point, where the exchange rate is 29.75, and the commission is 0.39 you will get (100 - 0.39) * 29.75 = 2963.3975RUR.
You surely know that there are N different currencies you can deal with in our city. Let us assign unique integer number from 1 to N to each currency. Then each exchange point can be described with 6 numbers: integer A and B - numbers of currencies it exchanges, and real RAB, CAB, RBA and CBA - exchange rates and commissions when exchanging A to B and B to A respectively.
Nick has some money in currency S and wonders if he can somehow, after some exchange operations, increase his capital. Of course, he wants to have his money in currency S in the end. Help him to answer this difficult question. Nick must always have non-negative sum of money while making his operations.


Input
The first line of the input contains four numbers: N - the number of currencies, M - the number of exchange points, S - the number of currency Nick has and V - the quantity of currency units he has. The following M lines contain 6 numbers each - the description of the corresponding exchange point - in specified above order. Numbers are separated by one or more spaces. 1<=S<=N<=100, 1<=M<=100, V is real number, 0<=V<=103.
For each point exchange rates and commissions are real, given with at most two digits after the decimal point, 10-2<=rate<=102, 0<=commission<=102.
Let us call some sequence of the exchange operations simple if no exchange point is used more than once in this sequence. You may assume that ratio of the numeric values of the sums at the end and at the beginning of any simple sequence of the exchange operations will be less than 104.
Output
If Nick can increase his wealth, output YES, in other case output NO to the output file.


Sample Input
3 2 1 20.0
1 2 1.00 1.00 1.00 1.00
2 3 1.10 1.00 1.10 1.00
Sample Output
YES


题意:判断自己原有资产通过兑换能不能变得更多?

解题思路:此题就是一道判断有没有负权回路的题,如果是负权回路,此时我们可以不断在这个回路中兑换,那钱不就想要多少就要多少吗?所以如果有负权回路,我们的资产就会变得更多,反之是不会的。判断有没有负权回路,我们可以采用spfa算法来实现。


AC代码:

/*
*邮箱:2825841950@qq.com
*blog:https://blog.csdn.net/hzf0701
*注:代码如有问题请私信我或在评论区留言,谢谢支持。
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<stack>
#include<queue>
#include<cstring>
#include<map>
#include<iterator>
#include<list>
#include<set>
#include<functional>
#include<memory.h>//G++编译器不支持,若使用G++编译器此段应注释掉
#include<iomanip>
#include<vector>
#include<cstring>
#define scd(n) scanf("%d",&n)
#define scf(n) scanf("%f",&n)
#define scc(n) scanf("%c",&n)
#define scs(n) scanf("%s",n)
#define prd(n) printf("%d",n)
#define prf(n) printf("%f",n)
#define prc(n) printf("%c",n)
#define prs(s) printf("%s",n)
#define rep(i,a,n) for (ll i=a;i<=n;i++)	  //i为循环变量,a为初始值,n为限定值,递增
#define per(i,a,n) for (ll i=a;i>=n;i--)//i为循环变量, a为初始值,n为界限值,递减。
#define pb push_back
#define fi first
#define se second
#define mp make_pair

using namespace std;

const int inf = 0x3f3f3f3f;//无穷大
const int maxn = 205;//最大值。
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll>  pll;
typedef pair<int, int> pii;
float money[maxn];//统计当前最大兑换金钱。
float rate[maxn][maxn];//rate[i][j]表示从i到j的汇率
float cost[maxn][maxn];//cost[i][j]表示从i到j的汇率
bool visited[maxn];//判断是否在队列中
int n,m,s;float v;//n:货币数量(即顶点数),m:兑换点数量(即边数),s:Nick用有的货币序号,Nick拥有的金钱。
	int to1,to2;float r1,c1,r2,c2;//对应交换点的描述
void init(){
	memset(money,0,sizeof(money));
	memset(visited,false,sizeof(visited));
	rep(i,1,n){
		rep(j,1,n){
			if(i==j)
				rate[i][j]=1;
			else rate[i][j]=0;
			cost[i][j]=0;
		}
	}
}
int spfa(int s){
	queue<int> q;
	q.push(s);
	money[s]=v;
	visited[s]=true;
	int temp;
	while(!q.empty()){
		temp=q.front();
		q.pop();
		visited[temp]=false;
		rep(i,1,n){
			if(money[i]<(money[temp]-cost[temp][i])*rate[temp][i]){
				money[i]=(money[temp]-cost[temp][i])*rate[temp][i];
				if(!visited[i]){
					q.push(i);
					if(money[s]>v)return 1;
					visited[i]=true;
				}
			}
		}
	}
	return 0;
}
int main(){
	//freopen("in.txt", "r", stdin);//提交的时候要注释掉
	ios::sync_with_stdio(false);//打消iostream中输入输出缓存,节省时间。
	cin.tie(0); cout.tie(0);//可以通过tie(0)(0表示NULL)来解除cin与cout的绑定,进一步加快执行效率。
	init();
	cin>>n>>m>>s>>v;
	rep(i,1,m){
		cin>>to1>>to2>>r1>>c1>>r2>>c2;
		rate[to1][to2]=r1;
		cost[to1][to2]=c1;
		rate[to2][to1]=r2;
		cost[to2][to1]=c2;
	}
	int result=spfa(s);
	if(result)cout<<"YES"<<endl;
	else cout<<"NO"<<endl;
	return 0;
}

posted @   unique_pursuit  阅读(38)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
点击右上角即可分享
微信分享提示