You now have N types of currencies. There are m exchange rate relationships between these N types of currencies. Then enter the group M relationship, A, rate, B, which means that A currency can be exchanged for B currency of rate per unit. Do you have any way to increase your money?
Idea: judge whether the ring is positive. The currency type is mapped to a number with MAP and then mapped. Set all your currencies to a principal of 1. Then Floyd ran to see if there was any money that made him a lot more. Or run Bellman Ford N times to see if there is a positive ring. When the relaxation condition is changed to that the weight can be increased, it can be relaxed.
Pit: pay attention to C + +, G + + may timeout.
Floyd:
//#include<bits/stdc++.h> #include<iostream> #include<cstdio> #include<string> #include<cstring> #include<map> using namespace std; const int MAXN = 35; int n, m; double d[MAXN][MAXN]; void Floyd() { for (int k = 0; k < n; k++) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { d[i][j] = max(d[i][j], d[i][k] * d[k][j]); } } } } int main() { int CASE = 1; while (~scanf("%d", &n) && n) { memset(d, 0, sizeof(d)); map<string, int> M; for (int i = 0; i < n; i++) { string str; cin >> str; M[str] = i; d[i][i] = 1; } scanf("%d", &m); while (m--) { string u, v; double rate; cin >> u >> rate >> v; d[M[u]][M[v]] = rate; } Floyd(); bool flag = false; for (int i = 0; i < n; i++) { if (d[i][i] > 1.0) { flag = true; break; } } printf("Case %d: ", CASE++); if (flag) printf("Yes\n"); else printf("No\n"); } return 0; } /* 3 USDollar BritishPound FrenchFranc 3 USDollar 0.5 BritishPound BritishPound 10.0 FrenchFranc FrenchFranc 0.21 USDollar 3 USDollar BritishPound FrenchFranc 6 USDollar 0.5 BritishPound USDollar 4.9 FrenchFranc BritishPound 10.0 FrenchFranc BritishPound 1.99 USDollar FrenchFranc 0.09 BritishPound FrenchFranc 0.19 USDollar 0 */
SPFA (queue optimization BellmanFord):
//#include<bits/stdc++.h> #include<iostream> #include<cstdio> #include<string> #include<cstring> #include<vector> #include<queue> #include<map> using namespace std; const int MAXN = 505; const int INF = 0x3f3f3f3f; struct Edge { int from, to/*, dist*/; //Start, end, distance double rate; //Edge(int u, int v, int w):from(u), to(v), dist(w) {} Edge(int u, int v, double w):from(u), to(v), rate(w) {} }; struct BellmanFord { int n, m; //Number of nodes and sides (including reverse arc) vector<Edge> edges; //Side table. edges[e] and edges[e^1] are opposite arcs to each other vector<int> G[MAXN]; //Adjacency table, G[i][j] indicates the serial number of the j-th edge of node i in the edges array bool vis[MAXN]; //In queue or not //int d[MAXN]; //Bellman-Ford double d[MAXN]; int p[MAXN]; //Previous arc int cnt[MAXN]; //Team entry times void init(int n) { this->n = n; edges.clear(); for (int i = 0; i <= n; i++) G[i].clear(); } //void add_edge(int from, int to, int dist) void add_edge(int from, int to, double rate) { //edges.push_back(Edge(from, to, dist)); edges.push_back(Edge(from, to, rate)); m = edges.size(); G[from].push_back(m - 1); } bool bellman_ford(int s) { for (int i = 0; i <= n; i++) d[i] = -INF; memset(vis, 0, sizeof(vis)); memset(cnt, 0, sizeof(cnt)); d[s] = 1; vis[s] = true; queue<int> Q; Q.push(s); while (!Q.empty()) { int u = Q.front(); Q.pop(); vis[u] = false; for (int i = 0; i < G[u].size(); i++) { Edge& e = edges[G[u][i]]; //if (d[u] < INF && d[e.to] > d[u] + e.dist) if (d[u] > -INF && d[e.to] < d[u] * e.rate) { //d[e.to] = d[u] + e.dist; d[e.to] = d[u] * e.rate; p[e.to] = G[u][i]; if (!vis[e.to]) { Q.push(e.to); vis[e.to] = true; if (++cnt[e.to] > n) return false;//Negative ring } } } } return true;//No negative ring } }; BellmanFord solve; int main() { int n, m, CASE = 1; while (~scanf("%d", &n) && n) { solve.init(n); map<string, int> M; for (int i = 0; i < n; i++) { string str; cin >> str; M[str] = i; } scanf("%d", &m); while (m--) { string u, v; double rate; cin >> u >> rate >> v; solve.add_edge(M[u], M[v], rate); } bool flag = false; for (int i = 0; i < n; i++) { if (!solve.bellman_ford(i)) { flag = true; break; } } printf("Case %d: ", CASE++); if (flag) printf("Yes\n"); else printf("No\n"); } return 0; } /* 3 USDollar BritishPound FrenchFranc 3 USDollar 0.5 BritishPound BritishPound 10.0 FrenchFranc FrenchFranc 0.21 USDollar 3 USDollar BritishPound FrenchFranc 6 USDollar 0.5 BritishPound USDollar 4.9 FrenchFranc BritishPound 10.0 FrenchFranc BritishPound 1.99 USDollar FrenchFranc 0.09 BritishPound FrenchFranc 0.19 USDollar 0 */