zoukankan      html  css  js  c++  java
  • 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
    ");
    86         else printf("No
    ");
    87     }
    88     return 0;
    89 }
  • 相关阅读:
    使用数字进行字符遍历
    注意:C++中double的表示是有误差的
    ER模型到关系模型的转换规则
    SQL中查询优化的主要策略
    分解成3NF保持函数依赖且为无损连接的算法
    函数依赖集闭包、属性集闭包、超键、候选键和最小函数依赖集的求法。
    分解成3NF的保持函数依赖的分解算法:
    模式分解是否为无损连接的判断方法
    字符串处理技巧
    sort+结构体实现二级排序
  • 原文地址:https://www.cnblogs.com/fzl194/p/8728865.html
Copyright © 2011-2022 走看看