POJ 1860(spfa+判斷正環)
阿新 • • 發佈:2018-12-11
題意:我們的城市有幾個貨幣兌換點。讓我們假設每一個點都只能兌換專門的兩種貨幣。可以有幾個點,專門從事相同貨幣兌換。每個點都有自己的匯率,外匯匯率的A到B是B的數量你1A。同時各交換點有一些佣金,你要為你的交換操作的總和。在來源貨幣中總是收取佣金。 例如,如果你想換100美元到俄羅斯盧布兌換點,那裡的匯率是29.75,而佣金是0.39,你會得到(100 - 0.39)×29.75=2963.3975盧布。 你肯定知道在我們的城市裡你可以處理不同的貨幣。讓每一種貨幣都用唯一的一個小於N的整數表示。然後每個交換點,可以用6個整數表描述:整數a和b表示兩種貨幣,a到b的匯率,a到b的佣金,b到a的匯率,b到a的佣金。 nick有一些錢在貨幣S,他希望能通過一些操作(在不同的兌換點兌換),增加他的資本。當然,他想在最後手中的錢仍然是S。幫他解答這個難題,看他能不能完成這個願望。
思路:如果從一個點出發回到這個點後金錢增加,那麼必定存在正環,所以用鄰接矩陣儲存,用spfa查出dis[sta]>v的情況。
#include<iostream> #include<vector> #include<queue> #include<cstring> using namespace std; const int maxn=1005; int n,m,s; double v; double rate[maxn][maxn],mon[maxn][maxn],dis[maxn]; bool spfa(int sta) { bool vis[maxn]; memset(vis,0,sizeof(vis)); memset(dis,0,sizeof(dis)); queue<int> q; dis[sta]=v; q.push(sta); vis[sta]=1; while(!q.empty()) { int x=q.front(); q.pop(); vis[x]=0; for(int i=1; i<=n; i++) { if(dis[i]<(dis[x]-mon[x][i])*rate[x][i]) { dis[i]=(dis[x]-mon[x][i])*rate[x][i]; if(dis[sta]>v) { return 1; } if(!vis[i]) { q.push(i); vis[i]=1; } } } } return 0; } int main() { ios::sync_with_stdio(false); while(cin>>n>>m>>s>>v) { for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { if(i!=j) { rate[i][j]=0; } else rate[i][j]=1; mon[i][j]=0; } } //cout<<m<<endl; for(int i=0; i<m; i++) { int a,b; double rab,mab,rba,mba; cin>>a>>b>>rab>>mab>>rba>>mba; rate[a][b]=rab; rate[b][a]=rba; mon[a][b]=mab; mon[b][a]=mba; } if(spfa(s)) { cout<<"YES"<<endl; } else cout<<"NO"<<endl; } return 0; }