此题有多种解法,注意到顶点最大为30(限制很小,不愧是模板练习题),可用Floyd算法求出整个图的最短路,注意此处并不是真正的最短路,但通过插点,即 i -> j 能否改成 i -> k -> j 的路,就会把环给考虑至少一次,那么对应的 path[i][i] 也就是本金肯定是增加的(相对于初值),为了方便,将本金设为 1 .
代码如下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
int n,m;
double dis[40][40];
map<string,int> money;
int main()
{
int cas = 1;
string s,ss;
double r;
while(~scanf("%d",&n) &&n)
{
memset(dis,0,sizeof(dis));
for(int i = 0;i < n;i++)
for(int j = 0;j < n;j++)
if(i == j)
dis[i][j] = 1;
for(int i = 0;i < n;i++)
{
cin >> s;
money[s] = i;
}
scanf("%d",&m);
for(int i = 0;i < m;i++)
{
cin >> s >> r >> ss;
dis[money[s]][money[ss]] = r;
}
for(int k = 0;k < n;k++)
for(int i = 0;i < n;i++)
for(int j = 0;j < n;j++)
if(dis[i][j] < dis[i][k] * dis[k][j])
dis[i][j] = dis[i][k] * dis[k][j];
printf("Case %d: ",cas++);
for(int i = 0;i < n;i++)
{
if(dis[i][i] > 1)
{
printf("Yes\n");
break;
}
else if(i == n - 1)
printf("No\n");
}
}
return 0;
}