您的位置:首页 > 编程语言 > C语言/C++

POJ 1860 bellman_ford

2013-10-05 22:09 363 查看
#include<iostream>
#include<fstream>
#include<cstdlib>

using namespace std;

//#define DEBUG

struct exchgpnt
{
int a;
int b;
double rab;
double cab;
};

static struct exchgpnt edges[100 * 2];
static int m, n, s;
static double v;
static double dst[101];

int bellman_ford(int edgenum)
{
int i, j;
memset(dst, 0, sizeof dst);
dst[s] = v;
for (i = 1; i < n; i++) /* relax edges */
{
for (j = 0; j < edgenum; j++)
{
int a, b;
double rab, cab;
a = edges[j].a;
b = edges[j].b;
rab = edges[j].rab;
cab = edges[j].cab;
if (dst[a] == 0.0)	continue;  /* 加上这句后运行时间减半 */
if (dst[b] < (dst[a] - cab) * rab)
{
if (b == s) return 1; /* 存在正向回路 */
dst[b] =  (dst[a] - cab) * rab;
}
}
}
for (j = 0; j < edgenum; j++)
{
int a, b;
double rab, cab;
a = edges[j].a;
b = edges[j].b;
rab = edges[j].rab;
cab = edges[j].cab;
if (dst[b] <  (dst[a] - cab) * rab)
{
return 1; /* 存在正向回路 */
}
}
return 0;
}

int main()
{
#ifdef DEBUG
fstream cin("G:\\book\\algorithms\\acm\\Debug\\dat.txt");
#endif
while (cin >> n >> m >> s >> v)
{
int i, p;
for (p = i = 0; i < m; i++)
{
int a, b;
double rab, rba, cab, cba;
//cin >> a >> b >> rab >> cab >> rba >> cba;
/* 采用下面的输入方式时间减到0MS */
scanf("%d%d%lf%lf%lf%lf", &a, &b, &rab, &cab, &rba, &cba);
edges[p].a = a; edges[p].b = b;
edges[p].cab = cab, edges[p++].rab = rab;

edges[p].a = b; edges[p].b = a;
edges[p].cab = cba, edges[p++].rab = rba;
}
if (bellman_ford(p))
printf("YES\n");
else
printf("NO\n");
}

return 0;
}

n种货币看成n个顶点,货币之间的转换就是顶点之间的边。这样输入数据就构成了一张图,问在图中是否存在从s------>s的正权回路。

就是s货币经过若干次兑换之后再换回s货币,数量会增加。基本思想和最短路径中的bellman_ford算法相同。bellman_ford算法以边

为输入。通过对全部的边做Relax操作n-1次,如果图中不存在负权回路,就能够得到从源点s到其他节点的最短路径的值。如果存在负

权回路,可以发现。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ POJ