用bellman_ford来判环,就是对所有边进行n-1次松弛,之后若还能进行松弛,则存在环。
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <map>
#define maxn 1005
using namespace std;
struct Edge
{
int from,to;
double rate;
}edge[maxn*maxn];
int n,m;
map<string,int> mp;
double G[maxn][maxn];
double dis[maxn];
int bellman_ford(int start,int end)
{
for(int i=1;i<=n;i++) //初始化
dis[i]=G[start][i];
dis[start]=1;
for(int i=1;i<n;i++) //进行n-1次松弛
{
for(int j=1;j<=m;j++)
{
if(dis[edge[j].from]*G[edge[j].from][edge[j].to]>dis[edge[j].to])
dis[edge[j].to]=dis[edge[j].from]*G[edge[j].from][edge[j].to];
}
}
int flag=0; //如果还能继续松弛,则存在环
for(int j=1;j<=m;j++)
{
if(dis[edge[j].from]*G[edge[j].from][edge[j].to]>dis[edge[j].to])
{
flag=1;
dis[edge[j].to]=dis[edge[j].from]*G[edge[j].from][edge[j].to];
break;
}
}
if(flag==1)
return 0;
return 1;
}
int main()
{
int cont=1;
while(scanf("%d",&n),n)
{
for(int i=1;i<=n;i++)
{
string s;
cin>>s;
mp[s]=i;
}
scanf("%d",&m);
getchar();
for(int i=1;i<=m;i++)
{
string u,v;
double r;
cin>>u>>r>>v;
edge[i].from=mp[u],edge[i].to=mp[v],edge[i].rate=r;
G[mp[u]][mp[v]]=r;
}
cout<<"Case "<<cont++<<": ";
if(bellman_ford(1,1)==0) //从1回到1,判断有没有环
printf("Yes\n");
else
printf("No\n");
}
return 0;
}