题目链接:http://poj.org/problem?id=1860
Description
Input
Output
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
Source
Description 一些货币兑换点正在我们的城市工作。我们假设每个兑换点尤其擅长兑换两种特定的货币,并且只进行对这些货币的兑换。可能有一些兑换点专门兑换相同的货币对。每个兑换点都有自己的汇率,货币A到货币B的汇率是你用1货币A换到的货币B的数量。每个兑换点也有一些佣金,即为你需要为你的兑换行动支付的金额。佣金总是从源货币扣除。 例如,如果你想要在汇率为29.75,并且佣金为0.39的兑换点将100美元兑换成俄罗斯卢布,你将会得到(100-0.39)*29.75=2963.3975卢布。 你有N种不同的货币可以在我们的城市进行兑换。我们为每一种货币制定从1到N的唯一一个整数。每个兑换点可以用6个数字形容:整数A和B——它交换的货币(表示为货币A和货币B);实数RAB,CAB,RBA和CBA——当它分别将货币A兑换成货币B和将货币B兑换成货币A时的汇率和佣金。 叫兽有一定数量的货币S,并且它希望它能以某种方式在一些兑换行动后增加它的资本。最后它的资金必须兑换为货币S。 帮助它解决这个棘手的问题。叫兽在进行它的兑换行动时资金总数必须始终非负。 Input 输入的第一行包含四个数字:N – 货币的数量,M – 兑换点的数量,S – 叫兽具有的货币种类,V – 叫兽具有的货币数量。 下面的M行每行包括6个数字 – 对相应的兑换点的描述。数字相隔一个或多个空格。1<=S<=N<=100,1<=M<=100,V是实数,0<=V<=10^3。 对于每个兑换点汇率和佣金都是实数,小数点后最多有两位小数。10^-2<=汇率<=10^2,0<=佣金<=10^2。 如果在一组兑换行动中没有兑换点被超过一次地使用,我们认为这组兑换行动是简单的。你可以认为最终数值和最初任何一个简单的兑换行动组的比例小于10^4。 Output 如果叫兽能增加它的财产,输出YES,否则输出NO。 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
思路:我们只需要寻找一下是否有正环存在就可以了!
代码如下:
#include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <climits> #include <ctype.h> #include <queue> #include <stack> #include <vector> #include <deque> #include <set> #include <map> #include <iostream> #include <algorithm> using namespace std; #define pi acos(-1.0) #define INF 0xffffff #define N 3005 #define M 2005 int Edgehead[N]; int cont[N]; double dis[N]; struct { int v,next; double rate, comm, w; }Edge[2*M]; bool vis[N]; int k; int n, m, s; double val; void Addedge(int u,int v,double r, double c) { Edge[k].next = Edgehead[u]; Edge[k].rate = r; Edge[k].v = v; Edge[k].comm = c; Edge[k].w = 0; Edgehead[u] = k++; } void init() { for(int i = 0 ; i < n ; i++ )//求最长路径开始设为0 dis[i] = 0; memset(Edgehead,-1,sizeof(Edgehead)); memset(vis,false,sizeof(vis)); memset(cont,0,sizeof(cont)); } int SPFA( int start) { queue<int>Q; dis[start] = val; vis[start] = true; ++cont[start]; Q.push(start); while(!Q.empty())//直到队列为空 { int u = Q.front(); Q.pop(); vis[u] = false; for(int i = Edgehead[u] ; i!=-1 ; i = Edge[i].next)//注意 { int v = Edge[i].v; Edge[i].w = (dis[u] - Edge[i].comm)*Edge[i].rate-dis[u]; if(dis[v] < dis[u] + Edge[i].w) { dis[v] = dis[u]+Edge[i].w; if( !vis[v] )//防止出现环,也就是进队列重复了 { Q.push(v); vis[v] = true; } if(++cont[v] > n)//有负环 return -1; } } } return 1; } int main() { while(~scanf("%d%d%d%lf",&n,&m,&s,&val))//n为目的地 { k = 0; init(); for(int i = 1 ; i <= m ; i++ ) { int a, b; double r, c; scanf("%d%d",&a,&b); scanf("%lf%lf",&r,&c); Addedge(a, b, r, c);//双向链表 scanf("%lf%lf",&r,&c); Addedge(b, a, r, c);//双向链表 } if(SPFA(s) == -1) { printf("YES\n"); } else printf("NO\n"); } return 0; }
poj 1860 Currency Exchange(SPFA),布布扣,bubuko.com
poj 1860 Currency Exchange(SPFA)
原文地址:http://blog.csdn.net/u012860063/article/details/38412685