题意:给定一些货币之间的单向汇率,问一笔钱能否经过若干次对换而增值。
分析:根据输入建立有向图,不能使用dijaskra,因为增值的方法不一定是优先选择最小的路径,并不是贪心所能解决的。所以要用以动态规划为基本思想的floyd来做。
#include <iostream> #include <string> #include <vector> using namespace std; const int maxn = 31; struct edge { int x; double l; edge(int xx, double ll):x(xx),l(ll) {} }; string names[maxn]; int n, m; double map[maxn][maxn]; bool found; int getid(string &a) { int i; for (i = 0; i < n; i++) if (a == names[i]) return i; return 0; } void init() { int i; string name1, name2; double l; getchar(); for (i = 0; i < n; i++) { cin >> names[i]; map[i][i] = 1; getchar(); } scanf("%d", &m); getchar(); for (i = 0; i < m; i++) { cin >> name1; cin >> l; cin >> name2; map[getid(name1)][getid(name2)]=l; } } void floyd() { int i, j, k; found = false; for (k = 0; k < n; k++) for (i = 0; i < n; i++) for (j = 0; j < n; j++) if (map[i][j] < map[i][k] * map[k][j]) map[i][j] = map[i][k] * map[k][j]; for (i = 0; i < n; i++) if (map[i][i] > 1) { found = true; break; } } int main() { int t = 0; //freopen("t.txt", "r", stdin); while (cin >> n && n != 0) { init(); found = false; printf("Case %d: ", ++t); floyd(); if (found) printf("Yes\n"); else printf("No\n"); } return 0; }