【最短路-判断正权环 Bellman-Ford】Arbitrage POJ

Arbitrage POJ - 2240

题意:

给出一系列货币汇率,问其中有无某种货币能在某些兑换操作后兑换回原货币,并且数量比开始时增多。

思路:

将货币视为节点,将兑换操作视为从一个节点到另一个节点的一条单向边。假定起点是1元,进行类似最短路的松弛操作后,再看起点是否多于1元即可。也就是判断是否存在正权环

Bellman-Ford

const int maxn = 40;

int num = 0;
map<string, int> currency
struct Edge {
    int from, to;
    double dist;
};
vector<Edge> edges;
double d[maxn];
int n, m;

void init(int n) {
    num = 0;
    edges.clear();
    currency.clear();
    memset(d, 0, sizeof(d));
}

bool solve(int s) {
    memset(d, 0, sizeof(d));
    d[s] = 1;
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < edges.size(); j++) {
            Edge& e = edges[j];
            if (d[e.from] * e.dist > d[e.to]) {
                d[e.to] = d[e.from] * e.dist;
            }
        }
    }
    if (d[s] > 1.0) return true;
    return false;
}

int main()
{
   // ios::sync_with_stdio(false);
   /// int t; cin >> t; while (t--) {
    int kase = 0;
    while (cin >> n && n) {
        init(n);
        for (int i = 1; i <= n; i++) {
            string s;
            cin >> s;
            currency[s] = i;
        }
        cin >> m;

        for (int i = 1; i <= m; i++) {
            string u, v;
            double dis;
            cin >> u >> dis >> v;
            Edge t;
            t.from = currency[u];
            t.to = currency[v];
            t.dist = dis;
            edges.push_back(t);
        }

        int ok = 0;

        for (int i = 1; i <= n; i++) {
            if (solve(i)) {
                ok = 1;
                break;
            }
        }
        cout << "Case " << ++kase << ": ";
        if (!ok) cout << "No" << endl;
        else cout << "Yes" << endl;
    }
   // }
    return 0;
}
原文地址:https://www.cnblogs.com/streamazure/p/13405091.html