POJ-2240 Arbitrage---判断正环+枚举

题目链接:

https://vjudge.net/problem/POJ-2240

题目大意:

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

思路:

由于这里问的是财富有没有增加,但是没有源点,所以可以枚举1-n为源点,分别用bellman-ford算法判断是否存在正环,如果有正环那就输出Yes,反之输出No。

这里还需要编号

其实可以用Floyd算法直接出结果判断有没有正环,这里用bellman-ford是卡着时间过的。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 #include<stack>
 8 #include<map>
 9 #include<set>
10 #include<sstream>
11 using namespace std;
12 typedef long long ll;
13 const int maxn = 1000 + 10;
14 const int INF = 1 << 25;
15 int T, n, m, cases, tot;
16 map<string, int>id;
17 set<string>cnt;
18 struct edge
19 {
20     int u, v;
21     double r;
22     edge(int u, int v, double r):u(u), v(v), r(r){}
23     edge(){}
24 };
25 edge a[maxn];
26 int getid(string s)
27 {
28     if(cnt.count(s))return id[s];
29     cnt.insert(s);
30     return id[s] = cnt.size();
31 }
32 double d[maxn];
33 bool Bellman(int u)
34 {
35     for(int i = 1; i <= n; i++)d[i] = 1.0 * INF;
36     d[u] = 1;
37     for(int i = 0; i < n; i++)
38     {
39         for(int j = 0; j < tot; j++)
40         {
41             int x = a[j].u, y = a[j].v;
42             double r = a[j].r;
43             if(d[x] * r > d[y])
44             {
45                 d[y] = d[x] * r;
46                 if(i == n - 1)return true;//第n次迭代还有更新说明存在正环
47             }
48         }
49     }
50     return false;
51 }
52 int main()
53 {
54     while(cin >> n && n)
55     {
56         string s;
57         cnt.clear();
58         id.clear();
59         tot = 0;
60         bool flag = 0;
61         for(int i = 0; i < n; i++)
62         {
63             cin >> s;
64             getid(s);
65         }
66         cin >> m;
67         string s1, s2;
68         double r;
69         for(int i = 0; i < m; i++)
70         {
71             cin >> s1 >> r >> s2;
72             int u = getid(s1);
73             int v = getid(s2);
74             a[tot++] = edge(u, v, r);
75         }
76         printf("Case %d: ", ++cases);
77         for(int i = 1; i <= n; i++)
78         {
79             if(Bellman(i))
80             {
81                 flag = 1;
82                 break;
83             }
84         }
85         if(flag)printf("Yes\n");
86         else printf("No\n");
87     }
88     return 0;
89 }

 

posted @ 2018-04-06 20:56  _努力努力再努力x  阅读(130)  评论(0编辑  收藏  举报