POJ 1860 Currency Exchange 解题报告
解题思路:改善了Bellman_ford算法,原来Bellman_ford算法是用来处理含负权边的最短路径,这题的路径能无限使用,用了spfa,有点bfs的味道。
#include <stdio.h>
#include<iostream>
#include <algorithm>
#include<string.h>
#include<cmath>
#include<queue>
#pragma warning(disable:4996)
#define inf 0x3f3f3f3f
#define ll unsigned long long
const int maxn = 100005;
using namespace std;
int n, m, s;
double dis[105], v, rate[105][105], cost[105][105];
int spfa(int start)
{
int vis[105];
memset(vis, 0, sizeof(vis));
memset(dis, 0, sizeof(dis));
dis[start] = v;
queue<int> qq;
qq.push(start);
vis[start] = 1;
while (!qq.empty())
{
int x = qq.front();
qq.pop();
vis[x] = 0;//代表这个位置没有数值
for (int i = 0; i <= n; i++)
{
if (dis[i] < (dis[x] - cost[x][i]) * rate[x][i])
{
dis[i] = (dis[x] - cost[x][i]) * rate[x][i];
if (dis[start] > v)//此时回到原点
return 1;
if (!vis[i])//已有数值时上面的dis会更新为最大情况,不用再搜索来传递数值了
{
qq.push(i);
vis[i] = 1;
}
}
}
}
return 0;
}
int main()
{
while (~scanf("%d%d%d%lf", &n, &m, &s, &v))
{
int a, b;
double rab, rba, cab, cba;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (i == j)
rate[i][j] = 1;
else
rate[i][j] = 0;
cost[i][j] = 0;
}
}
for (int i = 0; i < m; i++)
{
scanf("%d%d%lf%lf%lf%lf", &a, &b, &rab, &cab, &rba, &cba);
rate[a][b] = rab;
rate[b][a] = rba;
cost[a][b] = cab;
cost[b][a] = cba;
}
if (spfa(s))
printf("YES\n");
else
printf("NO\n");
}
}