主题思想 :
arbitrage 套利问题,可以转化为求最长路径问题,首先把所有节点间的利率初始化为0,然后求出本身到本身节点最大路径值。
如果是求指定两点的套利问题,可以用dijkstra,针对本题,是求的任意货币间所以用 floyd 求任意两点之间最短路径。
floyd 算法代码模板:
主要是初始化,和三层循环
//floyd init be to 0;
void inital(){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
g[i][j]=0;
}
}
}
void floyd(){
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
//here update condition
// 根据实际问题修改更新条件。
double tmp=g[i][k]*g[k][j];
if(g[i][j]<tmp){
g[i][j]=tmp;
}
}
}
}
}
AC 代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
using namespace std;
const int maxn=35;
int n,m;
double g[maxn][maxn];
//floyd init be to 0;
void inital(){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
g[i][j]=0;
}
}
}
void floyd(){
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
double tmp=g[i][k]*g[k][j];
if(g[i][j]<tmp){
g[i][j]=tmp;
}
}
}
}
}
int main()
{
int cnt=0;
while(scanf("%d",&n)!=EOF){
if(n==0)break;
cnt++;
map<string,int> currency;
string name;
for(int i=1;i<=n;i++){
cin>>name;
currency[name]=i;
}
//convert string to int
//init floyd
inital();
scanf("%d",&m);
string from,to;
double rate;
for(int i=1;i<=m;i++){
cin>>from>>rate>>to;
g[currency[from]][currency[to]]=rate;
}
// floyd
floyd();
//charge
bool flag=false;
//
for(int i=1;i<=n;i++){
if(g[i][i]>1.0) flag=true;
}
printf("Case %d: ",cnt);
if(flag){
printf("Yes\n");
}else{
printf("No\n");
}
}
return 0;
}