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
思路:
有多种汇币,汇币之间可以交换,这需要手续费,当你用100A币交换B币时,A到B的汇率是29.75,手续费是0.39,那么你可以得到(100 - 0.39) * 29.75 = 2963.3975 B币。问s币的金额经过交换最终得到的s币金额数能否增加。 货币的交换是可以重复多次的,所以我们需要找出是否存在正权回路,且最后得到的s金额是增加的。
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #define MAXN 110 using namespace std; double f[MAXN][MAXN],h[MAXN][MAXN],v,dis[MAXN]; int sum[MAXN],n,m,s; bool b[MAXN]; inline void read(int&x) { x=0;int f=1;char c=getchar(); while(c>‘9‘||c<‘0‘) {if(c==‘-‘) f=-1;c=getchar();} while(c>=‘0‘&&c<=‘9‘) {x=(x<<1)+(x<<3)+c-48;c=getchar();} x=x*f; } queue<int> q; inline bool spfa(int x) { memset(b,false,sizeof b); memset(dis,0,sizeof dis); memset(sum,0,sizeof sum); q.push(x); dis[x]=v; b[x]=true; while(!q.empty()) { int u=q.front(); q.pop(); b[u]=false; if(dis[x]>v) return true; for(int i=1;i<=n;i++) { if((dis[u]-h[u][i])*f[u][i]>dis[i]) { dis[i]=(dis[u]-h[u][i])*f[u][i]; if(!b[i]) { q.push(i); sum[i]++; b[i]=true; if(sum[i]>n) return true; } } } } return false; } int main() { while(scanf("%d%d%d%lf",&n,&m,&s,&v)!=EOF) { int x,y; for(int i=1;i<=m;i++) { read(x);read(y); scanf("%lf%lf%lf%lf",&f[x][y],&h[x][y],&f[y][x],&h[y][x]); } if(spfa(s)) printf("YES\n"); else printf("NO\n"); while(!q.empty()) q.pop(); } return 0; }
原文:http://www.cnblogs.com/whistle13326/p/6367911.html