题目链接: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