标签:
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
题意:要知道,每两种货币的兑换都是不同的,货币A-B和货币B-A也是不同的,所以经过一系列的货币兑换后,本来持有的钱会出现增加后减少的情况,那么现在知道货币现在的价值,种类,以及有多少种货币和转化方式,求经过一系列的兑换后回到最初的种类,价值是否增加(那么最短路中回路问题就出现了)。
#include<stdio.h> #include<queue> #include<algorithm> using namespace std; const int N=110; const int INF=0x3f3f3f3f; double C[N][N], R[N][N], dist[N], V; ///C数组保存货币兑换的利率,R数组保存货币兑换需要缴纳的值 int vis[N], cou[N], n, s; ///cou数组保存每个点遍历的次数,如果次数>=n的话说明出现回路了,代表价值值增加 void Init() { int i, j; for (i = 1; i <= n; i++) { dist[i] = -INF; cou[i] = vis[i] = 0; for (j = 1; j <= n; j++) C[i][j] = R[i][j] = -INF; C[i][i] = R[i][i] = 0; } } int Spfa(int u) { int i, v; queue<int>Q; Q.push(u); dist[u] = V; cou[u]++; while (!Q.empty()) { v = Q.front(); Q.pop(); for (i = 1; i <= n; i++) { if (dist[i] < (dist[v]-C[v][i])*R[v][i]) { dist[i] = (dist[v]-C[v][i])*R[v][i]; if (!vis[i]) { Q.push(i); vis[i] = 1; cou[i]++; if (cou[i] >= n) return 1; ///判断是否有回路,只需要判断是否存在回路的原因是dist[i]只有变大了才会进行这一步,即价值增加 } } } vis[v] = 0; } if (dist[s] > V) return 1; ///没有回路但是价值增加了也是可行的(感觉这一步像废话,如果增加了肯定是有回路存在啊!) return 0; } int main () { int m, a, b, ans; double r1, r2, c1, c2; while (scanf("%d %d %d %lf", &n, &m, &s, &V) != EOF) { Init(); while (m--) { scanf("%d %d %lf %lf %lf %lf", &a, &b, &r1, &c1, &r2, &c2); C[a][b] = c1; C[b][a] = c2; R[a][b] = r1; R[b][a] = r2; } ans = Spfa(s); if (ans) printf("YES\n"); else printf("NO\n"); } return 0; }
标签:
原文地址:http://www.cnblogs.com/syhandll/p/4812532.html