Currency Exchange
Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 19881   Accepted: 7114

Description

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

Source

Northeastern Europe 2001, Northern Subregion

Mean:

你有一些古币,现在你要用这些古币去兑换成其他钱币。这个城市里有N个兑换点,每个兑换点包括:
A----钱币A
B----钱币B
Rab--A兑换为B的比例
Cab--A兑换为B的手续费
Rba--B兑换为A的比例
Cba--B兑换为A的手续费
现在你有编号为S的这种古币,你将用这些古币去进行一系列的兑换,最终还是要兑换回古币。你想知道能不能通过一系列兑换来增加自身的古币。
N--钱币的种类总数(结点数)
M--兑换点的数量(边的条数)
S--你的货币种类标识(起点&终点)
V--你现在身上货币的数目

analyse:

判断图中是否存在正权回路。

使用spfa来不断迭代求最大路径,如果这个过程中某个点的迭代次数超过了n次,那么一定存在正权回路。

其实一般情况下每个点的迭代次数不会超过2,所以这题把n改为3也能过,当然如果存在正权回路的话一定会超过n,所以在不卡时间的情况下,就用n来判断保险一点。

Time complexity:O(m*k),k为每个点平均迭代次数

Source code:

//Memory   Time
// 164K 0MS
// by : Snarl_jsb
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<iomanip>
#include<string>
#include<climits>
#include<cmath>
#define MAXV 110
#define MAXE 110<<1
#define LL long long
using namespace std;
int n,m,sta;
float num;
int vis[MAXV];
float dis[MAXV];
int cnt[MAXV];
namespace Adj
{
struct Edge
{
int to,next;
float rate,cost;
};
Edge edge[MAXE];
int top;
int head[MAXV];
void init()
{
top=1;
memset(head,0,sizeof(head));
}
void addEdge(int u,int v,float rate,float cost)
{
edge[top].to=v;
edge[top].rate=rate;
edge[top].cost=cost;
edge[top].next=head[u];
head[u]=top++;
}
}
using namespace Adj; bool spfa()
{
for(int i=1;i<=n;i++)
cnt[i]=vis[i]=0,dis[i]=0.0;
queue<int>Q;
Q.push(sta);
vis[sta]=1;
dis[sta]=num;
while(!Q.empty())
{
int now=Q.front();
Q.pop();
vis[now]=0;
for(int i=head[now];i;i=edge[i].next)
{
int son=edge[i].to;
float tmp=(dis[now]-edge[i].cost)*edge[i].rate*1.0;
if(dis[son]<tmp)
{
dis[son]=tmp;
if(!vis[son])
{
Q.push(son);
vis[son]=1;
}
cnt[son]++;
if(cnt[son]>3) // 某个结点迭代次数超过了n次,存在正权回路
return false;
}
}
}
return true;
} int main()
{
// freopen("cin.txt","r",stdin);
// freopen("cout.txt","w",stdout);
scanf("%d %d %d %f",&n,&m,&sta,&num);
Adj:: init();
int a,b;
float r1,c1,r2,c2;
while(m--)
{
scanf("%d %d %f %f %f %f",&a,&b,&r1,&c1,&r2,&c2);
Adj:: addEdge(a,b,r1,c1);
Adj:: addEdge(b,a,r2,c2);
}
if(!spfa())
puts("YES");
else
puts("NO");
return 0;
}

  

图论 --- spfa + 链式向前星 : 判断是否存在正权回路 poj 1860 : Currency Exchange的更多相关文章

  1. 图论 ---- spfa + 链式向前星 ---- poj 3268 : Silver Cow Party

    Silver Cow Party Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 12674   Accepted: 5651 ...

  2. 图论 --- spfa + 链式向前星 (模板题) dlut 1218 : 奇奇与变形金刚

    1218: 奇奇与变形金刚 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 130  Solved: 37[Submit][Status][Web Boa ...

  3. 【数据结构】链式向前星知识点&代码

    代码: struct NODE{ int to; int nxt; int c; }node[MM];//链式向前星 ; void add(int a,int b,int c){ node[lcnt] ...

  4. Tarjan模版(链式向前星表示方法)

    这道模版用到了链式向前星表示法: struct node { int v,next; }edge[]; void add(int x,int y) { edge[++cnt].next=heads[x ...

  5. 【bfs+链式向前星】防御僵尸(defend)计蒜客 - 45288

    题目: A 国有 n 座城市,n−1 条双向道路将这些城市连接了起来,任何两个城市都可以通过道路互通. 某日,A 国爆发了丧尸危机,所有的幸存者现在都聚集到了 A 国的首都(首都是编号为 1 的城市) ...

  6. (简单) POJ 1860 Currency Exchange,SPFA判圈。

    Description Several currency exchange points are working in our city. Let us suppose that each point ...

  7. POJ 1860 Currency Exchange / ZOJ 1544 Currency Exchange (最短路径相关,spfa求环)

    POJ 1860 Currency Exchange / ZOJ 1544 Currency Exchange (最短路径相关,spfa求环) Description Several currency ...

  8. POJ 1860 Currency Exchange(最短路&spfa正权回路)题解

    题意:n种钱,m种汇率转换,若ab汇率p,手续费q,则b=(a-q)*p,你有第s种钱v数量,问你能不能通过转化让你的s种钱变多? 思路:因为过程中可能有负权值,用spfa.求是否有正权回路,dis[ ...

  9. POJ 1860 Currency Exchange【SPFA判环】

    Several currency exchange points are working in our city. Let us suppose that each point specializes ...

随机推荐

  1. 一用钟情的VS插件系列总目录(值得收藏)

    关于插件,大家的印象可能很多,比如开发者经常使用的Chrome浏览器的扩展程序,某个软件的一个扩展程序等等.我们使用插件的目的是为了提高我们的某些方面的工作效率或者让我们的软件源(Chrome浏览器等 ...

  2. Python黑客编程基础3网络数据监听和过滤

    网络数据监听和过滤 课程的实验环境如下: •      操作系统:kali Linux 2.0 •      编程工具:Wing IDE •      Python版本:2.7.9 •      涉及 ...

  3. Linux 通配符

    概述 本章节主要介绍关于linux通配符的用法,熟练运用通配符可以提高工作效率并且可以简化一些繁琐的处理步骤. 正文 测试数据 touch a a6.log abc.log ac.txt b c c5 ...

  4. 细说.NET中的多线程 (二 线程池)

    上一章我们了解到,由于线程的创建,销毁都是需要耗费大量资源和时间的,开发者应该非常节约的使用线程资源.最好的办法是使用线程池,线程池能够避免当前进行中大量的线程导致操作系统不停的进行线程切换,当线程数 ...

  5. MVVM架构~Knockoutjs系列之js接收C#数据集合的方式

    返回目录 在controller里将数据拿到,并且存储到ViewBag对象里,最后在View上显示出来,这是传统的MVC开发方式,事实上引入Knockoutjs以后,这种方式还是适合的,Knockou ...

  6. Ghost博客安装

    Ghost博客是一个基于Node.js 的开源博客平台,由前WordPress UI 部门主管John O'Nolan 和WordPress 高级工程师Hannah Wolfe 创立,目的是为了给用户 ...

  7. Java的概述以及语法

    Java的语法分为标示符和数据类型 Java的概述: 一些手打的: long l = 12345; //隐式转换 int a = (int)121234567L; //强制转换 float f =12 ...

  8. 用VC编译lua源码,生成lua语言的解释器和编译器

    用VC编译lua源码,生成lua语言的解释器和编译器 1.去网址下载源码 http://www.lua.org/download.html 2.装一个VC++,我用的是VC6.0 3.接下来我们开始编 ...

  9. DOM (Document Object Model)文档对象模型

    [理解下DOM] DOM——Document Object Mode.DOM是网页上XHTML中文档正文标题啊.段落.列表.样式.以及ID/class等所有其他数据的一个内部表示.我自己的理解是将网页 ...

  10. Linux初学 - 文件夹及文件操作

    创建文件夹 mkdir 移动文件夹 mv dir1 dir2 复制文件夹 cp 删除文件夹 rm 创建文件 touch 编辑文件内容 vi /vim 查看文件内容 cat 追加文件内容 echo 复制 ...