nyoj 183 赚钱啦【Bellman-Ford】

赚钱啦

时间限制:
1000 ms  |  内存限制:
65535 KB 难度:
5

描述

某国家里有N个城市,分别编号为0~N-1,一个精明的商人准备从0号城市旅行到N-1号城市,在旅行的过程中,从一个城市移动到另外一个城市需要有一定的花费,并且从A城市移动到B城市的花费和B城市移动到A城市的花费相同,但是,从A城市移动到B城市能赚取的钱和从B城市移动到A城市赚的钱不一定相同。

现在,已知各个城市之间移动的花费和城市之间交易可赚取的金钱,求该商人在从0号城市移动到N-1号城市的过程中最多能赚取多少钱?

输入
第一行是一个整数T(T<=10)表示测试数据的组数

每组测试数据的第一行是两个整数N,M表示,共有N个城市(1<N<=1000),M条路(1<=M<=1000)

随后的M行,每行有5个正整数,前两个数a,b(0<=a,b<N)表示两个城市的编号。后面的三个数c,u,v分别表示在a,b城市之间移动的花费,a城市移动到b城市可赚取的资金,b城市移动到a城市可赚取的资金。

(0<=c,u,v<=1000)

输出
如果商人能够在旅行过程中赚取无限多的资金,则输出$$$

否则输出他在移动过程中最多能赚取的资金数量

如果只会赔钱的话就输出一个负数,表示最少赔的钱数。

样例输入
2
2 1
0 1 10 11 11
3 3
0 1 10 16 0
1 2 10 15 5
0 2 20 32 0
样例输出
$$$

12

虽然调了几次代码,但是终于写对了。^><^

#include<stdio.h>
int n,m,k;
struct node
{
    int x,y,u;
} a[2010];
int dis[1010];
void init(int x,int y,int e)
{
    a[k].x=x;
    a[k].y=y;
    a[k++].u=e;
}
int Bellman_Ford()
{
    int i,j;
    for(i=0; i<n; i++)
        dis[i]=-1001;//初始值是权值的最小值+1
    dis[0]=0;
    for(i=1; i<n; i++)//n-1次松弛
        for(j=0; j<k; j++)
            if(dis[a[j].y]<(dis[a[j].x]+a[j].u))
                dis[a[j].y]=dis[a[j].x]+a[j].u;

    for(i=0; i<k; i++)//如果还能松弛,则为权正环
        if(dis[a[i].y]<(dis[a[i].x]+a[i].u))
            return 1;
    return 0;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int i,j,x,y,c,u,v,bj=0;
        k=0;
        scanf("%d%d",&n,&m);
        for(i=0; i<m; i++)
        {
            scanf("%d%d%d%d%d",&x,&y,&c,&u,&v);
            if((u-c>0&&v-c>=0)||(u-c>=0&&v-c>0))
            {
                bj=1;
                continue;
            }
            init(x,y,u-c);
            init(y,x,v-c);
        }
        if(bj==1||Bellman_Ford())
            printf("$$$\n");
        else
            printf("%d\n",dis[n-1]);

    }
}
    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/nuanxin_520/article/details/50489658
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞