I - Arbitrage POJ - 2240
题意: 利用汇率之间的差价判断是否可以赚钱
思路: 利用 spfa 跑最长路(即松弛条件改为取更大的值),判断是否存在正环,存在则可以赚钱
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
using namespace std;
const int maxn = 35;
int n, m;
int vis[maxn], cnt[maxn];
double dis[maxn];
struct node{
int to;
double w;
};
vector<node> G[maxn];
void init() {
memset(vis, 0, sizeof(vis));
memset(cnt, 0, sizeof(cnt));
for(int i = 1; i <= n; i++) G[i].clear();
}
bool spfa(int s) {
memset(dis, 0, sizeof(dis));
queue<int> Q;
Q.push(s);
dis[s] = 1;
vis[s] = 1;
cnt[s]++;
while(Q.size()) {
int u = Q.front(); Q.pop(); vis[u] = 0;
for(int i = 0; i < G[u].size(); i++) {
node e = G[u][i];
double dist = dis[u]*e.w;
if(dist - dis[e.to] > 1e-8) {
dis[e.to] = dist;
if(vis[e.to]) continue;
vis[e.to] = 1;
Q.push(e.to);
if(++cnt[e.to] > n) return 1;
}
}
}
return 0;
}
int main() {
// freopen("test.in", "r", stdin);
int kase = 0;
while(~scanf("%d", &n) && n) {
init();
string s;
map<string, int> money;
for(int i = 1; i <= n; i++) {
cin >> s;
money[s] = i;
}
scanf("%d", &m);
string u, v;
double rate;
for(int i = 1; i <= m; i++) {
cin >> u >> rate >> v;
// cout << u << rate << v << endl;
node e;
e.to = money[v]; e.w = rate;
G[money[u]].push_back(e);
}
if(spfa(1)) printf("Case %d: Yes\n", ++kase);
else printf("Case %d: No\n", ++kase);
}
return 0;
}