1 条题解
-
0
自动搬运
来自洛谷,原作者为

Created_equal1
**搬运于
2025-08-24 21:32:02,当前版本为作者最后更新于2015-08-12 20:51:31,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
把汇率表抽象成一个有向图,每个货币是一个结点,每条边上的权值就是汇率。
无法套利的情况分两种
1、没有环,即最后无法回到该种货币
2、有环,但是得到的利率不大于1
我们可以跑一遍单源最长路,用SPFA来判环,只是一般的松弛条件中的加号需要改成乘号。
可以证明如果环上所有边的权值之积大于1,那么一定可以用SPFA判定出有向图中存在环
( #include <map> #include <deque> #include <string> #include <cstdio> #include <cstring> #include <iostream> using namespace std; const size_t Max_N(35); const size_t Max_M(10000); size_t Adj[Max_M], Next[Max_M], Head[Max_N]; double Weight[Max_M]; double Dist[Max_N]; bool In_queue[Max_N]; unsigned int Times[Max_N]; unsigned int n, m; unsigned int fu; bool spfa(const size_t &S) { memset(Dist, 0, sizeof(Dist)); memset(In_queue, 0, sizeof(In_queue)); memset(Times, 0, sizeof(Times)); std::deque<size_t> Q; Dist[S] = 1.0; In_queue[S] = true; Q.push_back(S); Times[S] = 1; while (!Q.empty()) { size_t top = Q.front(); In_queue[top] = false; Q.pop_front(); for (int i = Head[top];i != 0;i = Next[i]) if (Dist[Adj[i]] < Dist[top] * Weight[i]) { Dist[Adj[i]] = Dist[top] * Weight[i]; if (!In_queue[Adj[i]]) { In_queue[Adj[i]] = true; Q.push_back(Adj[i]); ++Times[Adj[i]]; if (Times[Adj[i]] >= n) return true; } } } return false; } int main() { while (cin >> n, n) { unsigned int tot = 0; ++fu; memset(Adj, 0, sizeof(Adj)); memset(Next, 0, sizeof(Next)); memset(Head, 0, sizeof(Head)); memset(Weight, 0, sizeof(Weight)); map<string, unsigned int> v; string b, e; double number; for (unsigned int i = 1;i <= n;++i) v[(cin >> b), b] = i; cin >> m; while (m--) { ++tot; cin >> b >> number >> e; Adj[tot] = v[e]; Weight[tot] = number; Next[tot] = Head[v[b]]; Head[v[b]] = tot; } for (unsigned int i = 1;i <= n;++i) if (spfa(i)) { printf("Case %u: Yes\n", fu); goto loop; } printf("Case %u: No\n", fu); loop: ; } return 0; } )
- 1
信息
- ID
- 898
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者