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)

[HDOJ1217]Arbitrage(floyd)

HDOJ 1217 Arbitrage(拟最短路,floyd算法)

HDOJ 1217 Arbitrage (最短路)