给出货币名和汇率,问是否存在可以套汇的路径
即是否存在正环 SPFA
//是否存在正环 spfa
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
#include <map>
#include <string>
using namespace std;
const int MAXN=55;
const int MAXM=MAXN*MAXN/2;
const int INF=0x3f3f3f3f;
int head[MAXN],to[MAXM<<1],ne[MAXM<<1],n,m,ecnt,used[MAXN];
double wt[MAXM<<1],dist[MAXN];
map<string,int> hh;
void init()
{
ecnt=0;
memset(head,0,sizeof(head));
memset(used,0,sizeof(used));
hh.clear();
}
void addedge(int a,int b,double c)
{
ne[++ecnt]=head[a];
head[a]=ecnt;
to[ecnt]=b;
wt[ecnt]=c;
}
queue<int> q;
int vis[MAXN],inq[MAXN];
bool spfa(int s)//s为源点
{
while(!q.empty())
q.pop();
for(int i=1;i<=n;i++)
dist[i]=0,vis[i]=0,inq[i]=0;
dist[s]=100;//100块
q.push(s);
inq[s]=1;
double ta;
while(!q.empty())
{
int fr=q.front();
q.pop();
inq[fr]=0;
for(int k=head[fr];k;k=ne[k])
{
int v=to[k];
ta=dist[fr]*wt[k];
if(dist[v]<ta)
{
dist[v]=ta;
if(v==s)
return true;
if(inq[v])
continue;
if(++vis[v]>=n)//有正环
return true;
q.push(v);
inq[v]=1;
}
}
}
return false;
}
int main()
{
double ta;
char str[100],str2[100];
for(int kase=1;(scanf("%d",&n),n);kase++)
{
init();
for(int i=1;i<=n;i++)
{
scanf("%s",str);
hh[str]=i;
}
scanf("%d",&m);
for(int i=0;i<m;i++)
{
scanf("%s%lf%s",str,&ta,str2);
addedge(hh[str],hh[str2],ta);
}
bool ans=0;
for(int i=1;i<=n;i++)//防止不联通
{
if(used[i])continue;
if(spfa(i))
{
ans=1;
break;
}
for(int j=1;j<=n;j++)
if(dist[j])used[j]=1;
}
printf("Case %d: %s\n",kase,spfa(1)?"Yes":"No");
}
return 0;
}