#include <map>
#include <queue>
#include <string>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 35;
string str1, str2;
map <string, int> M; //将字符串映射成数字
int head[maxn], tot, n, m;
double w;
struct Edge{ //邻接表
int to, next;
double w;
}e[10005];
void addedge(int from, int to, double w){
e[tot].to = to;
e[tot].w = w;
e[tot].next = head[from];
head[from] = tot++;
}
bool spfa(int s){
bool vis[maxn]; //判断是否走过
int cnt[maxn]; //判断走了多少次
double d[maxn]; //相当于找最短路径,这里面其实就是兑换最大比例
memset(vis, false, sizeof(vis));
memset(cnt, 0, sizeof(cnt));
memset(d, 0, sizeof(d));
queue <int> que;
que.push(s);
d[s] = 1.0;
vis[s] = true;
while(!que.empty()){
int u = que.front();
que.pop();
vis[u] = false;
for(int i = head[u]; i != -1; i = e[i].next){
int v = e[i].to;
if(d[v] < d[u]*e[i].w){ //判断条件变了,因为要找最大的兑换比例
d[v] = d[u]*e[i].w;
if(!vis[v]){
vis[v] = true;
que.push(v);
if(++cnt[v] >= n) return true;
}
}
}
}
return false;
}
void init(){
memset(head, -1, sizeof(head));
tot = 0;
M.clear();
}
int main(){
int kase = 0;
while(scanf("%d", &n) != EOF && n){
init();
for(int i = 1; i <= n; i++){
cin >> str1;
M.insert(make_pair(str1, i));
}
scanf("%d", &m);
for(int i = 1; i <= m; i++){
cin >> str1 >> w >> str2;
addedge(M[str1], M[str2], w);
}
int flag = 0;
for(int i = 1; i <= n; i++)
if(spfa(i)){flag = 1; break;}
printf("Case %d: ", ++kase);
if(flag) puts("Yes");
else puts("No");
}
return 0;
}
HDU 1217 Arbitrage(最短路spfa判环)
最新推荐文章于 2019-01-04 13:43:12 发布