两种货币的交换可以当成两条边,建图后跑Bellman_ford算法就好了。
Bellman_ford算法可以用来处理负边权,所以可以判断是否存在负环。反过来就可以判断是否存在正环。
1 /*--------------------------------------------------------------------------------------*/ 2 // Helica's header 3 // Second Edition 4 // 2015.11.7 5 // 6 #include <algorithm> 7 #include <iostream> 8 #include <cstring> 9 #include <ctype.h> 10 #include <cstdlib> 11 #include <cstdio> 12 #include <vector> 13 #include <string> 14 #include <queue> 15 #include <stack> 16 #include <cmath> 17 #include <set> 18 #include <map> 19 20 //debug function for a N*M array 21 #define debug_map(N,M,G) printf(" ");for(int i=0;i<(N);i++) 22 {for(int j=0;j<(M);j++){ 23 printf("%d",G[i][j]);}printf(" ");} 24 //debug function for int,float,double,etc. 25 #define debug_var(X) cout<<#X"="<<X<<endl; 26 /*--------------------------------------------------------------------------------------*/ 27 using namespace std; 28 29 const int maxn = 100+10; 30 int N,M,T,S; 31 int tol; 32 double V; 33 34 struct Edge 35 { 36 int u,v; 37 double c,r; 38 }E[10*maxn]; 39 40 double dist[maxn]; 41 42 bool bellman_ford(int start,int n) 43 { 44 memset(dist,0,sizeof dist); 45 dist[start] = V; 46 47 for(int i=1;i<n;i++) 48 { 49 bool flag = false; 50 for(int j=0;j<tol;j++)if(dist[E[j].v] < (dist[E[j].u]-E[j].c)*E[j].r ) 51 { 52 dist[E[j].v] = (dist[E[j].u]-E[j].c)*E[j].r; 53 flag = true; 54 } 55 if(!flag) return false; 56 } 57 58 for(int j=0;j<tol;j++) 59 { 60 if(dist[E[j].v] < (dist[E[j].u]-E[j].c)*E[j].r) 61 return true; 62 } 63 return false; 64 } 65 66 int main() 67 { 68 while(~scanf("%d%d%d%lf",&N,&M,&S,&V)) 69 { 70 int a,b; 71 double r1,r2,c1,c2; 72 tol = 0; 73 for(int i=0;i<M;i++) 74 { 75 scanf("%d%d%lf%lf%lf%lf",&a,&b,&r1,&c1,&r2,&c2); 76 E[tol].u = a;E[tol].v = b; 77 E[tol].c = c1;E[tol++].r = r1; 78 E[tol].u = b;E[tol].v = a; 79 E[tol].c = c2;E[tol++].r = r2; 80 } 81 if(bellman_ford(S,N)) 82 printf("YES "); 83 else 84 printf("NO "); 85 86 } 87 }