Bellman_ford货币兑换——正权回路判断

POJ1860

题目大意:你在某一点有一些钱,给定你两点之间钱得兑换规则,问你有没有办法使你手里的钱增多。就是想看看转一圈我的钱能不能增多,出现这一点得条件就是有兑换钱得正权回路,所以选择用bellman_ford得算法

准备工作,bellman_ford得更新是根据已知边得数据来的,所以需要存住边的数据,还要有dis数组作为更新判断,dis也就相当于中心节点得钱兑换到i节点(中间可能会经过别的)变成了多少钱

#include <iostream>
#include <string.h>
#include <cstdio>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 110;
struct node{
    int from,to;
    double r,c;
}edge[maxn * 2];
double d[maxn];

 根据题意,存储边的数据

for(int i = 1;i <= m * 2;i++)
        {
            scanf("%d %d %lf %lf %lf %lf",&a,&b,&r1,&c1,&r2,&c2);
            edge[i].from = a;edge[i].to = b;
            edge[i].r = r1;edge[i].c = c1;
            i++;
            edge[i].from = b;edge[i].to = a;
            edge[i].r = r2;edge[i].c = c2;
        }

 进行bellman_ford算法,进行钱财得初始化,初始化d时要根据其含义和松弛得判断条件来进行初始化,然后松弛n次,再进行判断,如果还能松弛,那就代表有正权回路返回True~~

bool Bellman_ford(int n,int s,double v,int len)
{
    for(int i = 1;i <= n;i++)d[i] = 0.0;

    d[s] = v;

    for(int i = 1;i <= n;i++)
    {
        bool flag = true;
        for(int j = 1;j <= len ;j++)
        {
            int from = edge[j].from;
            int to = edge[j].to;
            double r = edge[j].r;
            double c = edge[j].c;
            if(d[to] < (d[from] - c) * r)
            {
                d[to] = (d[from] - c) * r;
                flag = false;
            }
        }
        if(flag)return false;
    }
    for(int i = 1;i <= len;i++)
    {
        if(d[edge[i].to] < (d[edge[i].from] - edge[i].c) * edge[i].r)
        {
            return true;
        }
    }
    return false;

}
原文地址:https://www.cnblogs.com/DF-yimeng/p/8524789.html