题解:
题目分析
题意是判断是否可以进行套利,就是判断图内是否存在一个圈,当经过这个圈回到终点时自己的钱是否可以增多。dis数组存的是同种货币进行汇兑的最大值。当“松弛”进行n次时,肯定存在圈的情况,这样的话,如果dis[v0] > 1的话,说明可以进行汇兑。
#include<cstdio>
#include<iostream>
#include<map>
#include<cstring>
#include<string>
using namespace std;
const int MAXN = 40;
struct Edge
{
int u,v;
double w;
};
Edge e[MAXN * MAXN];
double dis[MAXN];
int n,m;
bool bellman_ford(int v0)
{
memset(dis,0,sizeof(dis));
dis[v0] = 1;
for(int i = 1; i <= n;++i) // 松弛的边的次数
{
for(int j = 1;j <= m;++j)
{
dis[e[j].v] = max(dis[e[j].v],(dis[e[j].u] * e[j].w));
}
}
if(dis[v0] > 1)
{
return 1;
}
else
{
return 0;
}
}
int main()
{
int t = 1;
while(cin >> n && n)
{
map<string,int> M;
for(int i = 1; i <= n;++i)
{
string temp;
cin >> temp;
M[temp] = i;
}
cin >> m;
int cnt = 1;
int k = m;
while(k--)
{
string s1,s2;
double w;
cin >> s1 >> w >> s2;
e[cnt].u = M[s1];
e[cnt].v = M[s2];
e[cnt].w = w;
cnt++;
}
int flag = 0;
cout << "Case " << t++ << ": ";
for(int i = 1; i <= n; ++i)
{
bool ans;
ans = bellman_ford(i);
if(ans)
{
flag = 1;
cout << "Yes" << endl;
break;
}
}
if(!flag)
cout << "No" << endl;
}
return 0;
}
总结一下 bellman-ford的优点就是可以进行判圈造圈。