POJ 1860 汇率 SPFA
题意
有多种汇币,汇币之间可以交换,这需要手续费,当你用100A币交换B币时,A到B的汇率是29.75,手续费是0.39,那么你可以得到(100 - 0.39) * 29.75 = 2963.3975 B币。问s币的金额经过交换最终得到的s币金额数能否增加 货币的交换是可以重复多次的,所以我们需要找出是否存在正权回路,且最后得到的s金额是增加的 怎么找正权回路呢?(正权回路:在这一回路上,顶点的权值能不断增加即能一直进行松弛)
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算法进行改造,原来的dis改为存的货币的数量,改为求最长路,如果有自环,那么dis会不断增加没有上限
if(money[v]<(money[u]-E[u][i].fee)*E[u][i].rate){
money[v]=(money[u]-E[u][i].fee)*E[u][i].rate;
if(!vis[v])
#define _CRT_SBCURE_NO_DEPRECATE
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <bitset>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define ll long long
#define mm0(a) memset(a,0,sizeof(a))
#define mm(a,b) memset(a,b,sizeof(a))
#define each(a,b,c) for(int a=b;a<=c;a++)
#define de(x) cout << #x << " " << (x) <<endl
//#define de(x) cout <<""
#define rush() int T;scanf("%d",&T);each(kase,1,T)
#define scan(a,b) scanf("%d%d",&a,&b)
#define fin(a) scanf("%d",&a)
using namespace std;
const int maxn = 1e3+5;
const int INF = 0x3f3f3f3f;
inline int read(){int s=0;char ch=getchar();for(; ch<'0'||ch>'9'; ch=getchar());for(; ch>='0'&&ch<='9'; ch=getchar())s=s*10+ch-'0';return s;}
/*
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
*/
struct Edge{
int v;
double fee;
double rate;
Edge(int _v,double _fee,double _rate):v(_v),fee(_fee),rate(_rate){}
};
vector<Edge>E[maxn];
void addEdge(int u,int v,double fee,double rate)
{
E[u].push_back(Edge(v,fee,rate));
}
bool vis[maxn];
int cnt[maxn];
double money[maxn];
int n;
int m;
int start;
double init_money;
bool SPFA(int start,double init_money,int n)
{
memset(vis,false,sizeof(vis));//清空vis
for(int i=1;i<=n;i++)money[i]=0;
vis[start]=true;
money[start]=init_money;
queue<int>Q;
while(!Q.empty())Q.pop();
Q.push(start);
memset(cnt,0,sizeof(cnt));
cnt[start]=1;
while(!Q.empty())
{
int u=Q.front();
Q.pop();
vis[u]=false;
for(int i=0;i<E[u].size();i++)
{
int v=E[u][i].v;
if(money[v]<(money[u]-E[u][i].fee)*E[u][i].rate){
money[v]=(money[u]-E[u][i].fee)*E[u][i].rate;
if(!vis[v])
{
vis[v]=true;
Q.push(v);
if(++cnt[v]>n)return false;
}
}
}
}
return true;
}
int main()
{
scanf("%d%d%d%lf",&n,&m,&start,&init_money);
each(i,1,m)
{
int a,b;
double rab,cab,rba,cba;
scan(a,b);
scanf("%lf%lf%lf%lf",&rab,&cab,&rba,&cba);
addEdge(a,b,cab,rab);
addEdge(b,a,cba,rba);
}
if(!SPFA(start,init_money,n))
cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}