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 }
To Be The Best Of Yourself