题意:给定一些货币之间的单向汇率,问一笔钱能否经过若干次对换而增值。
分析:根据输入建立有向图,不能使用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;
}