题目大意:n种货币,m种兑换汇率,求是否存在某种货币经过一些兑换之后获得更多的价值。
题目分析:建图求最长路。存在兑换关系的货币直接建一条有向边,从某个货币出发,假设该货币初始值为1,求一条最长路,乘上路径上所有的汇率,最后回到该货币,如果价值增加了,输出Yes,如果n种货币均不存在这种情况,No。
这题Floyd也可以做。
详情请见代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 33;
const int M = 1000;
char dict[N][N];
double dis[N];
int n,m;
struct node
{
int ci,cj;
double cij;
}edge[M];
int num;
char s[100];
int find()
{
int i;
for(i = 1;i <= n;i ++)
if(strcmp(s,dict[i]) == 0)
return i;
}
bool BellmanFord(int st)
{
int i,j;
for(i = 1;i <= n;i ++)
dis[i] = 0;
dis[st] = 1.0;
for(i = 1;i <= n;i ++)//回路,要找n条边!!
{
for(j = 0;j < num;j ++)
{
if(dis[edge[j].cj] < dis[edge[j].ci] * edge[j].cij)
dis[edge[j].cj] = dis[edge[j].ci] * edge[j].cij;
}
}
if(dis[st] > 1.0)
return true;
else
return false;
}
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
int i,j,cas;
cas = 0;
while(scanf("%d",&n),n)
{
for(i = 1;i <= n;i ++)
scanf("%s",dict[i]);
scanf("%d",&m);
num = 0;
while(m --)
{
scanf("%s",s);
edge[num].ci = find();
scanf("%lf",&edge[num].cij);
scanf("%s",s);
edge[num ++].cj = find();
}
for(i = 1;i <= n;i ++)
if(BellmanFord(i))
break;
printf("Case %d: ",++cas);
if(i <= n)
puts("Yes");
else
puts("No");
}
return 0;
}
//152K 63MS