HDU 1217 Arbitrage(Bellman-Ford判断负环+Floyd)
Posted Yeader
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 1217 Arbitrage(Bellman-Ford判断负环+Floyd)相关的知识,希望对你有一定的参考价值。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1217
题目大意:问你是否可以通过转换货币从中获利
如下面这组样例:
USDollar 0.5 BritishPound
BritishPound 10.0 FrenchFranc
FrenchFranc 0.21 USDollar
可以通过US->Br->French->US这样转换,把1美元变成1*0.5*10*0.21=1.05美元赚取%5的利润。
解题思路:其实就相当于bellman-ford里的负环判断,负环的意思是沿着走一圈回到原点后路径会变短了。这里我们可以把路径的减小转化为货币价值的增加,如果最后回到起点(i==V-1)继续更新别的点(i==V),说明起点价值相对原来变大了。也可以用floyd写,查看个点价值是否变大。
1 #include<iostream> 2 #include<string> 3 #include<map> 4 #include<queue> 5 using namespace std; 6 const int N=35; 7 const int INF=1<<30-1; 8 struct edge{ 9 int from,to; 10 double rate; 11 }eg[N*N]; 12 13 int V,E; 14 double d[N]; 15 16 bool bellman_ford(int s){ 17 for(int i=1;i<=V;i++){ 18 d[i]=0; 19 } 20 d[s]=1.0;//初始货币为1 21 22 for(int i=1;i<=V;i++){ 23 for(int j=1;j<=E;j++){ 24 edge e=eg[j]; 25 //这里是判断会不会变大 26 if(d[e.to]<d[e.from]*e.rate){ 27 d[e.to]=d[e.from]*e.rate; 28 if(i==V) return true;//想当于d[s]>1.0 29 } 30 } 31 } 32 return false; 33 } 34 35 int main(){ 36 int cas=0; 37 while(cin>>V&&V){ 38 map<string,int>mp; 39 string s; 40 for(int i=1;i<=V;i++){ 41 cin>>s; 42 mp[s]=i; 43 } 44 cin>>E; 45 for(int i=1;i<=E;i++){ 46 string s1,s2; 47 double rate; 48 cin>>s1>>rate>>s2; 49 eg[i].from=mp[s1]; 50 eg[i].to=mp[s2]; 51 eg[i].rate=rate; 52 } 53 bool flag=false; 54 //对每种货币都尝试一遍 55 for(int i=1;i<=V;i++){ 56 flag=bellman_ford(i); 57 if(flag){ 58 cout<<"Case "<<++cas<<": Yes"<<endl; 59 break; 60 } 61 } 62 if(!flag) 63 cout<<"Case "<<++cas<<": No"<<endl; 64 } 65 return 0; 66 }
Floyd:
1 #include<iostream> 2 #include<string> 3 #include<map> 4 using namespace std; 5 const int N=35; 6 const int INF=1<<30-1; 7 8 int V,E; 9 double val[N][N]; 10 11 void floyd(){ 12 for(int k=1;k<=V;k++){ 13 for(int i=1;i<=V;i++){ 14 for(int j=1;j<=V;j++){ 15 if(val[i][j]<val[i][k]*val[k][j]) 16 val[i][j]=val[i][k]*val[k][j]; 17 } 18 } 19 } 20 } 21 22 int main(){ 23 int cas=0; 24 while(cin>>V&&V){ 25 map<string,int>mp; 26 //路径初始化为0,各个点初始化为1 27 for(int i=1;i<=V;i++){ 28 for(int j=1;j<=V;j++){ 29 val[i][j]=(i==j?1:0); 30 } 31 } 32 for(int i=1;i<=V;i++){ 33 string s; 34 cin>>s; 35 mp[s]=i; 36 } 37 cin>>E; 38 for(int i=1;i<=E;i++){ 39 string s1,s2; 40 double trate; 41 cin>>s1>>trate>>s2; 42 val[mp[s1]][mp[s2]]=trate; 43 } 44 floyd(); 45 bool flag=false; 46 //每个点都看一遍是否可以获得利益 47 for(int i=1;i<=V;i++){ 48 if(val[i][i]>1){ 49 flag=true; 50 break; 51 } 52 } 53 if(flag){ 54 cout<<"Case "<<++cas<<": Yes"<<endl; 55 } 56 else{ 57 cout<<"Case "<<++cas<<": No"<<endl; 58 } 59 } 60 }
以上是关于HDU 1217 Arbitrage(Bellman-Ford判断负环+Floyd)的主要内容,如果未能解决你的问题,请参考以下文章
HDU 1217 Arbitrage(最短路径,Floyd算法)
HDU 1217 Arbitrage(Bellman-Ford判断负环+Floyd)
[ACM] hdu 1217 Arbitrage (bellman_ford最短路,推断是否有正权回路或Floyed)