Bellman-Ford算法的应用。
请参考:http://www.cnblogs.com/freezhan/p/3238968.html
至于里面说的:
注意:
这里的松弛操作要循环 N 次才能过,
书上的松弛操作一直都是 N-1 次
对于为什么是 N 或者 N-1 次一直没有理解清楚
是因为这题目会测试很坑的样例,比如:
input:
1
a
1
a 1.5 a
output:
Yes
这样是一条头尾都是自己的节点的边,如果不循环n次,会直接忽略这条边……这样答案就会出错。
#include<cstdio>
#include<iostream>
#include<map>
using namespace std;
struct Edge{
int u,v;
double r;
}edge[5000];
int n,m;
double d[40];
void init(int st)
{
for(int i=1;i<=n;i++) d[i]=0;
d[st]=1;
}
void relax(int u,int v,double r){if(d[v] < d[u]*r) d[v]=d[u]*r;}
bool bellman_ford(int st)
{
init(st);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++) relax(edge[j].u,edge[j].v,edge[j].r);
}
if(d[st]>1.0) return false;
return true;
}
int main()
{
int kase=0;
while(scanf("%d",&n) && n!=0)
{
map<string,int> currency;
for(int i=1;i<=n;i++)
{
string str;
cin>>str;
currency[str]=i;
}
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
string str1,str2;double r_tmp;
cin>>str1>>r_tmp>>str2;
edge[i].u=currency[str1];
edge[i].v=currency[str2];
edge[i].r=r_tmp;
}
bool flag=true;
for(int i=1;i<=n;i++)
{
if(bellman_ford(i)==false)
{
flag=false;
break;
}
}
if(flag==false) printf("Case %d: Yes\n",++kase);
else printf("Case %d: No\n",++kase);
}
}