题目大意:
现有n种货币以及m种交换方式(1 ≤ n, m ≤ 100),n中货币编号1 ~ n,现给出每种交换方式的汇率以及手续费,形式为"u v r1 c1 r2 c2",其中u、v为两种货币的编号,r1、c1为u兑换到v的汇率以及手续费,而r2、c2为v兑换到u的汇率以及手续费,如果手上有u货币f元,则可兑换到v货币(f - c1)r1元,其中10^-2 ≤ r ≤ 10^2, 0 ≤ c ≤ 10^2,除货币编号外其余都是浮点数。
现只有一个测例,给出以上信息,以及初始拥有的货币s和货币钱数v,求是否存在一种兑换方式,使得从s开始,兑换一圈回到s后使得到的钱数比起始钱数要大,若存在则输出"YES",否则输出"NO"。
注释代码:
/*
* Problem ID : POJ 1860 Currency Exchange
* Author : Lirx.t.Una
* Language : C
* Run Time : 16 ms
* Run Memory : 176 KB
*/
#include <stdio.h>
//最大货币种数
#define MAXN 100
//有向图最大边数
#define MAXM 200
typedef struct {//有向边
//u->v汇率为r手续费为c
int u, v;
double r, c;
} Arc;
Arc arc[MAXM];//有向边
double dis[MAXN + 1];//belf的当前最短路径长度
int e;//边数
void
addarc( int u, int v, double r, double c ) {
arc[e].u = u;
arc[e].v = v;
arc[e].r = r;
arc[e].c = c;
e++;
}
int
belf(int n) {//Bellman-Ford求是否存在能无限松弛的正环
int cont;
int k, i;
double tmp;
for ( cont = 1, k = 1; cont && k <= n; k++ )
for ( cont = 0, i = 0; i < e; i++ )//注意,现在是求最大路径
if ( ( tmp = ( dis[ arc[i].u ] - arc[i].c ) * arc[i].r ) > dis[ arc[i].v ] ) {
if ( k == n ) return 1;
dis[ arc[i].v ] = tmp;
cont = 1;
}
return 0;
}
int
main() {
int n, m;//n种货币,m种交换方式
int s;//起始货币
double vv;//起始钱数
int u, v;
double r, c;
int i;
scanf("%d%d%d%lf", &n, &m, &s, &vv);
dis[s] = vv;//初始化,自己到自己不经过其它边就是起始钱数
while ( m-- ) {
scanf("%d%d%lf%lf", &u, &v, &r, &c);
addarc( u, v, r, c );
scanf("%lf%lf", &r, &c);
addarc( v, u, r, c );
}
if ( belf(n) ) puts("YES");
else puts("NO");
return 0;
}
无注释代码:
#include <stdio.h>
#define MAXN 100
#define MAXM 200
typedef struct {
int u, v;
double r, c;
} Arc;
Arc arc[MAXM];
double dis[MAXN + 1];
int e;
void
addarc( int u, int v, double r, double c ) {
arc[e].u = u;
arc[e].v = v;
arc[e].r = r;
arc[e].c = c;
e++;
}
int
belf(int n) {
int cont;
int k, i;
double tmp;
for ( cont = 1, k = 1; cont && k <= n; k++ )
for ( cont = 0, i = 0; i < e; i++ )
if ( ( tmp = ( dis[ arc[i].u ] - arc[i].c ) * arc[i].r ) > dis[ arc[i].v ] ) {
if ( k == n ) return 1;
dis[ arc[i].v ] = tmp;
cont = 1;
}
return 0;
}
int
main() {
int n, m;
int s;
double vv;
int u, v;
double r, c;
int i;
scanf("%d%d%d%lf", &n, &m, &s, &vv);
dis[s] = vv;
while ( m-- ) {
scanf("%d%d%lf%lf", &u, &v, &r, &c);
addarc( u, v, r, c );
scanf("%lf%lf", &r, &c);
addarc( v, u, r, c );
}
if ( belf(n) ) puts("YES");
else puts("NO");
return 0;
}