POJ 2240 -- Arbitrage(Bellman-Ford)

Posted Amysear

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2240 -- Arbitrage(Bellman-Ford)相关的知识,希望对你有一定的参考价值。

POJ 2240 -- Arbitrage(Bellman-Ford)

题意:

已知n种货币,以及m种货币汇率及方式,问能否通过货币转换,使得财富增加。

Bellman-ford 算法:

一个具有n个顶点的图如果不存在环,则从顶点x,到顶点y,最多经过n-1条边(要考虑连通性,每个顶点最多经过 1 次),因此 x 到 y 的最短路 最多经过 n - 1 次松弛操作(就是更新长度)就应该出现,如果第 n 次松弛还可以得到最优,那么这个图就肯定是存在环了(直接用Dijkstra 就无法得到最优的,环的存在会影响最优解是否存在)。

 

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 const int maxn = 50;//顶点的最大值 
 5 const int maxm = 1000;//边数的最大值 
 6 #define max(a,b) {(a)>(b)?(a):(b)}
 7 struct node{
 8     int ci,cj;
 9     double cij;
10 }exch[maxm];///兑换货币的路径 
11 
12 double dist[maxn];//源点到其他每个节点的最长路径,包括它本身 
13 
14 char name[maxn][20];
15 int n,m;
16 bool flag;
17 int kase = 1;
18 void solve_case(int v0)
19 {//Bellman-Ford算法:以v0为源点,求它到每个顶点(包含它本身)的最大距离
20      flag = false;
21      memset(dist,0,sizeof(dist));
22      dist[v0] = 1;
23      for(int k=1;k<=n;k++)//从dist(0)递推到dist(1)...dist(n) 进行n次松弛操作
24       {
25           for(int i=0;i<m;i++)//判断每一条边,假如他是否能使最大距离增加 
26           {
27               if(dist[exch[i].ci]*exch[i].cij > dist[exch[i].cj])
28               {
29                   dist[exch[i].cj] = dist[exch[i].ci]*exch[i].cij;
30               }
31           }
32       }
33       if(dist[v0]>1.0) flag = true;
34 }
35 
36 int cin_case()
37 {
38     while(cin>>n && n)
39     {
40         //输入货币的名称 ,name数组下标即为货币的编号 
41         for(int i=0;i<n;i++){
42             cin>>name[i]; 
43         }
44         ///输入兑换货币的路径 
45         cin>>m;
46         char a[20],b[20];
47         double e; 
48         for(int i=0;i<m;i++)
49         {
50             cin>>a>>e>>b;
51             ///得到货币的编号
52             int k,j;
53             for(k=0;strcmp(name[k],a)!=0;k++);
54             for(j=0;strcmp(name[j],b)!=0;j++);
55             ///从k->j 汇率为e 
56             exch[i].ci = k;exch[i].cj = j;exch[i].cij = e; 
57         }
58         return 1;
59     }
60     return 0;
61 }
62 
63 int main()
64 {
65     while(cin_case())
66     {
67         for(int i=0;i<n;i++)
68         {
69             solve_case(i);//从第i个结点出发求最长路径
70             if(flag) break; 
71         }
72         if(flag) cout<<"Case "<<kase++<<": Yes"<<endl;
73         else cout<<"Case "<<kase++<<": No"<<endl;
74      } 
75     
76     return 0;
77  } 

 

以上是关于POJ 2240 -- Arbitrage(Bellman-Ford)的主要内容,如果未能解决你的问题,请参考以下文章

POJ2240:Arbitrage(最长路+正环)

POJ 2240 Arbitrage

poj 2240 Arbitrage 题解

POJ 2240 Arbitrage (spfa判环)

Arbitrage POJ - 2240

poj2240 Arbitrage (spfa判环)