题目链接:
http://acm.split.hdu.edu.cn/showproblem.php?pid=1217
题意:
给出一些货币的汇率,求能不能套利润。
题解:
此题可以转化为求最短路,只是最短路的求法变成了乘法,而且此题不可以使用dijstra,因为<1时就相当于加法里的负权环了,还要注意使用floyd时不可以加上i!=j!=k的条件,因为最后是要回到原点的。
AC代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <map>
#include <string>
using namespace std;
double dist[50][50];
int n,m,cnt;
double w;
map <string, int> money;
void floyd()
{
for(int k = 0; k < n; k++)
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
if(dist[i][k] * dist[k][j] > dist[i][j])
dist[i][j] = dist[i][k] * dist[k][j];
}
int main()
{
cnt = 1;
while(~scanf("%dist", &n))
{
if(n == 0)break;
string a,u,v;
int b,c;
for(int i = 0; i < n; i++)
{
cin >> a;
money[a] = i;
}
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
if(i == j)
dist[i][j] = 1;
else
dist[i][j] = 0;
}
}
scanf("%d", &m);
while(m--)
{
cin >> u >> w >> v;
b = money[u], c = money[v];
dist[b][c] = w;
}
floyd();
int flag = 0;
for(int i = 0; i < n; i++)
{
if(dist[i][i] > 1)
{
flag = 1;
break;
}
}
if(flag)
printf("Case %d: Yes\n", cnt++);
else
printf("Case %d: No\n", cnt++);
}
return 0;
}