题目大意:
n种货币(1 ≤ n ≤ 30),m组兑换方式(单向),对换方式的格式为"str_name1 r str_name2",其中前后两个str为货币的字符串名字(中间不含空格),r为汇率(为浮点数),现有多个测例,每个测例中给出n以及n中货币的名字,接着给出m以及m中对换方式,对于每个测例输出是否可以套汇,如果可以则输出"Yes"否则输出"No"。
与POJ 1860 Currency Exchange类似!
代码:
/*
* Problem ID : POJ 1860 Currency Exchange
* Author : Lirx.t.Una
* Language : C++
* Run Time : 47 ms
* Run Memory : 236 KB
*/
#include <iostream>
#include <cstring>
#include <string>
#include <map>
#define MAXN 30
#define MAXM 900
using namespace std;
struct Arc { int u, v; double r; };
Arc arc[MAXM];
double dis[MAXN];
int e;
map<string,char> mp;
void
addarc( int u, int v, double r ) {
arc[e].u = u;
arc[e].v = v;
arc[e].r = r;
e++;
}
bool
belf(int n) {
bool cont;
int k, i;
double tmp;
cont = true;
for ( k = 1; k <= n; k++ )
for ( cont = false, i = 0; i < e; i++ )
if ( ( tmp = dis[ arc[i].u ] * arc[i].r ) > dis[ arc[i].v ] ) {
if ( k == n ) return true;
dis[ arc[i].v ] = tmp;
cont = true;
}
return false;
}
int
main() {
int iscn;
int n, m;
int u, v;
int i;
double r;
string str;
iscn = 0;
while ( scanf("%d", &n), n ) {
memset(dis, 0, sizeof(dis));
dis[0] = 1.0;
for ( i = 0; i < n; i++ ) {
cin >> str;
mp[str] = i;
}
e = 0;
scanf("%d", &m);
while ( m-- ) {
cin >> str;
u = mp[str];
scanf("%lf", &r);
cin >> str;
v = mp[str];
addarc( u, v, r );
}
printf("Case %d: ", ++iscn);
if ( belf(n) ) puts("Yes");
else puts("No");
}
return 0;
}