poj 2240 Floyd判斷有向圖負環(arbitrage)
阿新 • • 發佈:2019-01-29
題意:Arbitrage問題(套匯)。給定若干幣種及一些幣種轉換的匯率,問能否有套匯的可能。
思路:如果以幣種為定點,匯率為邊建圖,則相當於求一個圈,其上權值乘積大於1。將權值取對數再取負,變成求有向圖負環。用floyd演算法即可。(直接上Floyd,三層迴圈中判斷直接用乘法也OK)。另外用spfa判斷應該也行,只需將每個點都入隊一次。
#include <stdio.h> #include <string.h> #include <math.h> #define min(a,b) ((a)<(b)?(a):(b)) #define N 35 char name[N][128]; int c=1,n,m; double g[N][N]; int find(char* x){ int i; for(i = 1;i<=n;i++) if(!strcmp(name[i], x)) return i; return -1; } int main(){ while(scanf("%d",&n) && n){ int i,j,k,a,b; char s[128],t[128]; double w; for(i = 1;i<=n;i++) for(j = 1;j<=n;j++) g[i][j] = 0x3fffffff; for(i = 1;i<=n;i++) scanf("%s",name[i]); scanf("%d",&m); for(i = 0;i<m;i++){ scanf("%s %lf %s",s,&w,t); a = find(s); b = find(t); g[a][b] = -log10(w); } for(k = 1;k<=n;k++) for(i = 1;i<=n;i++) for(j = 1;j<=n;j++) g[i][j] = min(g[i][j],g[i][k]+g[k][j]); for(i = 1;i<=n;i++) if(g[i][i] < 0) break; if(i<=n) printf("Case %d: Yes\n",c++); else printf("Case %d: No\n",c++); } return 0; }