http://acm.hdu.edu.cn/showproblem.php?pid=1217
题意:给几个国家,然后给这些国家之间的汇率。判断能否通过这些汇率差进行套利交易。
Floyd的算法可以求出任意两点间的最短路径,最后比较本国与本国的汇率差,如果大于1,则可以。否则不可以。
最短路径,Floyd的算法原理:
Floyd-Warshall算法的原理是动态规划。
设D(i,j,k)为从i到j的只以集合中的k节点为中间节点的最短路径的长度。
若最短路径经过点k,则;D(i,j,k)=D(i,k)+D(k,j)
若最短路径不经过点k,则D(i,j,k)=D(i,j,k-1)。
因此,D(i,j,k)=min{D(i,k)+D(k,j),D(i,j,k-1)}。
在实际算法中,为了节约空间,可以直接在原来空间上进行迭代,这样空间可降至二维。
算法描述:
for k ← 1 to n do
for i ← 1 to n do
for j ← 1 to n do
if (D(i,k)+D(k,j)<D(i,j)) then
D(i,j)← D(i,k)+D(k,j);
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
#define N 31
string countries[N];
double relation[N][N];
int find(string s,int n){
int mid=-1,high=n-1,low=0;
while (low<=high){
mid=(low+high)/2;
if (countries[mid]==s)
return mid;
else if (countries[mid]<s)
low=mid+1;
else high=mid-1;
}
return -1;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("1217in.txt","r",stdin);
#endif
int n,i,m,p,q,ce=0;
string a,b;
double t;
while (scanf("%d",&n)!=EOF&&n){
ce++;
memset(relation,0,sizeof(relation));
for (i=0;i<n;i++){
cin>>countries[i];
relation[i][i]=1;
}
sort(countries,countries+n);
scanf("%d",&m);
while (m--){
cin>>a>>t>>b;
p=find(a,n);
q=find(b,n);
relation[p][q]=t;
}
for (i=0;i<n;i++)
for (p=0;p<n;p++)
for (q=0;q<n;q++)
if (relation[p][i]*relation[i][q]>relation[p][q])
relation[p][q]=relation[p][i]*relation[i][q];
for (i=0;i<n;i++)
if (relation[i][i]>1)
break;
if (i>=n)
printf("Case %d: No\n",ce);
else printf("Case %d: Yes\n",ce);
}
return 0;
}