zoukankan      html  css  js  c++  java
  • poj 1860 Currency Exchange(Bellman_ford)

    最短路问题,但是刚开始的时候没什么想法,因为看到题目中要求回到源点,但是最短路都是求一个点到另一个点的最短路,想到要处理环,就有点头疼,因为对最短路理解的不透彻,又上网认真的学了学求最短路的各种方法。

    Dijkskra:贪心的思想,从源点开始,先查看所有与源点相连的点,找出一条最短的路,然后从这个点重复上一个过程,直到找到目标点。要求图上的权值为非负数,时间复杂度为O(n2)。

    Floyd:这是我认为写法最简单,也是最容易理解的一种算法,可以想成一个图中只有三个点,判断一下,是源点直接到终点近,还是通过中间那个点间接的到终点近,如果通过间接的点近,就更新,由此推到有n个点的图中,所以三重循环即可。该算法可以处理负权边,但是没法处理负环,时间复杂度为O(n3)。

    Bellman_ford:应该说这是一种万能的算法吧,效率也很高。我认为这是Dijkskra的改善,它是假设所有与源点相连的点到源点的路都是最短的,然后进行更新,这样最多就有N-1点与源点相连,也就是最多更新N-1次,如果N-1次后还能接着更新,那么就说明图中有环,所有这种方法可以处理负权环。时间复杂度为O(n2),如果用邻接表表示图可以是复杂度降至O(E)。

    再来说说这题,这题的意思是有N种货币进行换算,给出两种货币的汇率和手续费,求是否可以进过若干次换算可以使原来的钱增多。做完后才知道这题真的很水,直接套Bellman_ford模板就行了,但是没有思路才是最大的障碍!要多想想啊。

    代码:

    View Code
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <math.h>
    #include <queue>
    #define  N 204
    using namespace std ;
    
    struct node{
        int v , u ;
        double r , c ;
    }p[N] ;
    
    int n , m , s ;
    double v ;
    
    int Bellman_ford( int num )
    {
        double dis[N] ;
        int i ;
        memset( dis , 0 , sizeof ( dis )) ;
        dis[s] = v ;
        while ( dis[s] <= v )
        {
            int flag = 0 ;
            for( i = 0 ; i < num ; i++ )
            {
                double tp = ( dis[p[i].u] - p[i].c ) * p[i].r ;
                if ( dis[p[i].v] < tp )
                {
                    flag = 1 ;
                    dis[p[i].v] = tp ;
                }
            }
            if ( !flag )//判断是否更新
            return dis[s] > v ;
        }
        return 1 ;
    }
    
    int main()
    {
        int i , x , y ;
        double rx , cx ;
    
        while ( scanf ( "%d%d%d%lf" , &n , &m , &s , &v ) != EOF )
        {
            int num = 0;
            for ( i = 1 ; i <= m ; i++ )
            {
                scanf ( "%d%d" , &x , &y );
                scanf ( "%lf%lf" , &rx ,&cx );
                p[num].u = x ;
                p[num].v = y ;
                p[num].r = rx ;
                p[num].c = cx ;
                scanf ( "%lf%lf" , &rx , &cx );
                p[++num].u = y ;
                p[num].v = x ;
                p[num].r = rx ;
                p[num].c = cx ;
                num++ ;
            }
            if ( Bellman_ford( num ) )
            printf ( "YES\n" );
            else
            printf ( "NO\n" );
        }
        return 0 ;
    }
  • 相关阅读:
    HDU 4358 莫队算法+dfs序+离散化
    HDU 5692 线段树+dfs序
    Codeforces Round #377 (Div. 2) A B C D 水/贪心/贪心/二分
    LVS负载均衡的三种模式和八种算法总结
    hdfs 常用命令
    Linux 系统监控
    CentOS 7 时区设置
    kubernetes 留言版DEMO
    CentOS7 PostgreSQL 主从配置( 三)
    Postgres数据库在Linux中优化
  • 原文地址:https://www.cnblogs.com/misty1/p/2721917.html
Copyright © 2011-2022 走看看