标签:
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
题目大意:给你n种货币,m种货币交换关系,交换率和手续费,给你起始的货币类型和金额,问你是否可以通过交换货币,最后回到起始的货币时能盈利。
解题思路:如果要盈利,只需要判断图中存不存在正环, 即可以一直让某种货币额度无限增加。由于是无向图,那么只要存在正环,那么我就可以最后转化成起始的货币且盈利。所以只要将SPFA判负环的条件变化一下就行。初始值时,让除原点之外的d数组都赋值为0。同时松弛条件变为d[e.to] < (d[e.from] - e.com)*e.rate。即可,最后判断当u为起点时的d[u]是否大于起始金额即可。
#include<stdio.h> #include<algorithm> #include<string.h> #include<queue> #include<vector> #include<iostream> using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 1e3+200; int n , m; struct Edge{ int from,to; double rate , com; }; vector<Edge>edges; vector<int>G[maxn]; void init(){ for(int i = 0; i <= n; i++){ G[i].clear(); } edges.clear(); } double d[maxn] ,cnt[maxn], inq[maxn]; void AddEdge(int u,int v,double r,double co){ edges.push_back( (Edge){u,v,r,co} ); m = edges.size(); G[u].push_back(m-1); } bool SPFA(int s, double V){ queue<int>Q; for(int i = 0; i <= n; i++){ d[i] = 0; } d[s] = V; cnt[s] ++; inq[s] = 1; Q.push(s); while(!Q.empty()){ int u = Q.front(); Q.pop(); if(u == s&& d[s] > V){ return true; } inq[u] = 0; for(int i = 0; i < G[u].size(); i++){ Edge & e = edges[G[u][i]]; if(d[e.to] < (d[e.from] - e.com)*e.rate ){ d[e.to ] = (d[e.from] - e.com) *e.rate; if(!inq[e.to]){ inq[e.to] = 1; Q.push(e.to); } } } } return false; } int main(){ int mm,s; double k; while(scanf("%d%d%d%lf",&n,&mm,&s,&k)!=EOF){ int a,b; double c,d; for(int i = 0; i < mm; i++){ scanf("%d%d%lf%lf",&a,&b,&c,&d); AddEdge(a,b,c,d); scanf("%lf%lf",&c,&d); AddEdge(b,a,c,d); } bool yes = SPFA(s,k); if(yes){ puts("YES"); }else{ puts("NO"); } } return 0; }
POJ 1860——Currency Exchange——————【最短路、SPFA判正环】
标签:
原文地址:http://www.cnblogs.com/chengsheng/p/4903388.html