POJ 1860 Currency Exchange

这题还是学到了一点东西吧。

题目链接:http://poj.org/problem?id=1860

题意就是有N个货币兑换点,每个点提供A,B两种货币的兑换。

假设现在手上有货币A,数量为Q,那么兑换成货币B的话就能得到(Q-Cab)*Rab 个B货币。

初始货币为S,数量为V,求能不能通过一系列兑换,增加S的数量。

这个就是最短路,用Bellman-Ford算法拉,松弛后看图中有没有正环(因为要增加货币数量)。

不过不需要松弛n-1次,可以在松弛的过程中看,此时的图G能不能提供松弛的边,如果不能就直接跳出n-1的循环。

关键在于松弛条件:dis[ fun[j].f ] - fun[j].c ) * fun[j].r  >  dis[ fun[j].t ]。

        即若把f兑换成t,t的数量要大于原来t的数量。

还有一个坑,就是所有货币(除开s)的初始数量要设成0,不能是负数,要不然到后面检查正环的时候就会有坑。

上代码

 1 #include<stdio.h>
 2 #include<iostream>
 3 using namespace std;
 4 #include<queue>
 5 #include<math.h>
 6 #include<algorithm>
 7 #include<string.h>
 8 
 9 #define repA(p,q,i)  for( int (i)=(p); (i)!=(q); ++(i) )
10 #define repAE(p,q,i)  for( int (i)=(p); (i)<=(q); ++(i) )
11 #define repD(p,q,i)  for( int (i)=(p); (i)!=(q); --(i) )
12 #define repDE(p,q,i)  for( int (i)=(p); (i)>=(q); --(i) )
13 #define EMAX 210
14 #define VMAX 110
15 #define MAXN 0x3f3f3f3f
16 struct node{
17     int f,t;    
18     float c,r;
19     node(){}
20     node( int _f , int _t , float _c , float _r )
21         : f(_f) , t(_t) , c(_c) , r(_r) {}
22 };
23 
24 int n,m,s,a,b,order;
25 float q,rab,cab,rba,cba;
26 node fun[EMAX] ;
27 float dis[VMAX];
28 
29 bool Bellman();
30 int main()
31 {
32     while( scanf("%d%d%d%f",&n,&m,&s,&q) != EOF )
33     {
34         order=0;
35         repA(0,m,i)
36         {
37             scanf("%d%d%f%f%f%f",&a,&b,&rab,&cab,&rba,&cba);
38             fun[order++] = node( a,b,cab,rab ) ;
39         
40             fun[order++] = node( b,a,cba,rba ) ;            
41         }
42         printf("%s\n", Bellman()==true ? "YES" : "NO" ) ;
43     }
44     return 0;
45 }
46 
47 bool Bellman()
48 {    
49     repA(0,VMAX,i)
50         dis[i]=0;
51     dis[s] = q ;
52     float temp;
53     bool flag;
54     int i;
55     for(i=1; i!=n; ++i)
56     {       flag = false ;
57         repA(0,order,j)  
58         {
59 
60             temp = ( dis[ fun[j].f ] - fun[j].c ) * fun[j].r ;
61             if( temp > dis[ fun[j].t ] )
62             {
63                  dis[ fun[j].t ] = temp ;
64                 flag = true ;
65             }
66         }
67         if( !flag )  break ;
68     }
69     repA(0,order,j)
70     {
71         if( ( dis[ fun[j].f ] - fun[j].c ) * fun[j].r > dis[ fun[j].t ] )
72             return true ;
73     }
74     return false;
75 }
View Code

 

posted on 2013-09-09 11:10  码农之上~  阅读(231)  评论(0编辑  收藏  举报

导航