poj1860 Currency Exchange (bellman_ford)

/*
有多种汇币,汇币之间可以交换,这需要手续费

货币的交换是可以重复多次的,所以我们需要找出是否存在正权回路,且最后得到的s金额是增加的
怎么找正权回路呢?(正权回路:在这一回路上,顶点的权值能不断增加即能一直进行松弛)
*/
# include <stdio.h>
# include <algorithm>
# include <string.h>
using namespace std;
struct node
{
    int u;
    int v;
    double r;
    double c;
};
node map[250];
int tot;
int id;
double num;
double dis[110];
int n;
int bellman_ford()
{
    int i,j,flag;
    memset(dis,0,sizeof(dis));//这里与bellman的目的刚好相反。初始化为源点到各点距离无穷小  
    dis[id]=num;       //即bellman本用于找负环,求最小路径,本题是利用同样的思想找正环,求最大路径 
    for(i=1;i<=n;i++)
    {
        flag=0;
        for(j=0;j<tot;j++)
        {
            if(dis[map[j].v]<(dis[map[j].u]-map[j].c)*map[j].r) //寻找最长路径  
            {                                                   //进行比较的是"某点到自身的权值"和"某点到另一点的权
                dis[map[j].v]=(dis[map[j].u]-map[j].c)*map[j].r;
                flag=1;
            }
        }
        if(flag==0)
            break;
    }
    for(i=0;i<tot;i++)
    {
        if(dis[map[i].v]<(dis[map[i].u]-map[i].c)*map[i].r)   //正环能够无限松弛  
            return 1;
    }
    return 0;
}
int main()
{
    int m,a,b;
    double r1,r2,c1,c2;
    while(~scanf("%d%d%d%lf",&n,&m,&id,&num))
    {
        tot=0;
        while(m--)
        {
            scanf("%d%d%lf%lf%lf%lf",&a,&b,&r1,&c1,&r2,&c2);
            map[tot].u=a;
            map[tot].v=b;
            map[tot].r=r1;
            map[tot++].c=c1;
            map[tot].u=b;
            map[tot].v=a;
            map[tot].r=r2;
            map[tot++].c=c2;
        }
        if(bellman_ford())
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值