SP9340 题解

前言

题目:三倍经验。SP9340UVA436P1931

更好的阅读体验?

趣味的 Floyd。

思路

容易发现,套利就是一大堆兑换的数值的成绩。我们希望这个数值大于 \(1\)

可以想到,每次把两个兑换名称转化为一个数,然后建边 \(a \to b\),边权为汇率 \(k\)

题目就是求边权乘积最大环(有点绕,自行理解)。

注意到 \(n\) 很小,用 Floyd 即可。

最后答案就是 \(e_{1, 1}\)

代码

#include <iostream>
#include <cstdio>
#include <map>
#include <cstring>
using namespace std;
int n;
double e[35][35];
bool solve()
{
	map <string, int> mp; //将字符串转化为值
	for (int i = 1; i <= n; i++)
	{
		string s;
		cin >> s;
		mp[s] = i;
	}
	memset(e, -127, sizeof(e)); //double 类型,要用 -127 初始化,表示赋值无穷小
	int m;
	cin >> m;
	while (m--)
	{
		string u, v; double k;
		cin >> u >> k >> v;
		e[mp[u]][mp[v]] = k;
	}
	for (int k = 1; k <= n; k++) //floyd
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				e[i][j] = max(e[i][j], e[i][k] * e[k][j]); //小改动
	return e[1][1] > 1;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	for (int T = 1;; T++)
	{
		cin >> n;
		if (n == 0) break;
		bool ans = solve();
		cout << "Case " << T << ": ";
		if (ans) cout << "Yes\n"; else cout << "No\n";
	}
	return 0;
}

希望能帮助到大家!

posted @ 2022-10-31 21:57  liangbowen  阅读(24)  评论(0编辑  收藏  举报