NYOJ 188 Arbitrage
View Code
1 /* 2 题意: 3 货币之间存在着转换 ,从一种货币转换到 4 另一种货币有有一个转换率,有没有这种情况 5 一种货币经过几次转换再回到这个货币时 6 会增值 7 8 思路: 9 这相当与一个路径问题,找到各个点的最大距离 10 每次从一条边的左边的货币开始转换,看是否能 11 增值 有几条边循环几次 12 */ 13 #include<iostream> 14 #include<cstring> 15 16 using namespace std; 17 18 struct node 19 { 20 int a,b; 21 double r; 22 }E[10000];//存 储 从 a 到 b 及 转 换 率 r 23 double d[2001];//存 储 各种货币顶点 24 char a[32][100]; 25 double dmin=0.0000001; 26 27 int main() 28 { 29 int n,m,i,flag,evu,ct=0,t1,t2,j; 30 double rab; 31 char cha[30],chb[30]; 32 while(cin>>n&&n) 33 { 34 ++ct; 35 memset(E,0,sizeof(E)); 36 for(i=0;i<n;++i) 37 { 38 cin>>a[i]; 39 } 40 cin>>m; 41 42 for(i=0;i<m;++i) 43 { 44 cin>>cha>>rab>>chb; 45 for(j=0;j<n;++j) 46 { 47 if(strcmp(cha,a[j])==0)t1=j; 48 if(strcmp(chb,a[j])==0)t2=j; 49 } 50 E[i].a=t1; 51 E[i].b=t2; 52 E[i].r=(rab > E[i].r ? rab : E[i].r);//注意两个点之间有多个点 53 } 54 evu=0;//判断是否可以增值 55 56 for(int j=0;j<m;++j) 57 { 58 memset(d,0,sizeof(d)); 59 int temp=E[j].a;//依次以 每条边的左端为起点 60 d[temp]=1; 61 62 while(d[temp]<=1+dmin) 63 { 64 flag=0; 65 66 for(i=0;i<m;++i) 67 if(d[E[i].b]+dmin<d[E[i].a]*E[i].r) 68 { 69 d[E[i].b]=d[E[i].a]*E[i].r; 70 flag=1; 71 } 72 73 if(!flag)//如果没有更新则跳出 74 { 75 // if(d[temp]>1+dmin)evu=1; 76 break; 77 } 78 } 79 80 if(flag)//是由于 d[temp]<=1 + dimin跳出循环的 81 { 82 evu=1; 83 break; 84 } 85 } 86 87 if(evu)cout<<"Case "<<ct<<": Yes"<<endl<<endl; 88 else cout<<"Case "<<ct<<": No"<<endl<<endl; 89 } 90 // system("pause"); 91 return 0; 92 } 93