题目链接<http://poj.org/problem?id=1860>
题意:
有N个国家,他们之间的货币可以互相进行兑换。货币的兑换会涉及到手续费和汇率。兑换是双向的,但手续费和汇率有可能不同。假设某人拥有S国家的货币V元,他是否可以进行货币的兑换,使得他最后获得的S国家的货币变多。
题解:
因为每个国家被访问的次数是没有限制的,所以如果能使钱变多,就必然存在一个正环。
SPFA可以处理环的问题,无论是正环还是负环。
#include <iostream>
#include <cstdio>
#include <queue>
#include <string.h>
using namespace std;
struct Edge{
int to,next;
double rate,com;
Edge(int to=0,int next=0,double rate=0,double com=0):to(to),next(next),rate(rate),com(com){}
}e[205];
int n,m,x;double val;
double dis[205];
int head[205],now=-1;
void add(int a,int b,double c,double d){
e[++now]=Edge(b,head[a],c,d);head[a]=now;
}
int vis[205],cnt[205];
int spfa(){
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
queue<int>q;
q.push(x);
vis[x]=cnt[x]=1;dis[x]=val;
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(dis[v]<(dis[u]-e[i].com)*e[i].rate){
dis[v]=(dis[u]-e[i].com)*e[i].rate;
if(!vis[v]){
q.push(v);
vis[v]=1;cnt[v]++;
if(cnt[v]>n) return 1;
}
}
}
}
return 0;
}
int main(){
while(cin>>n>>m>>x>>val){
memset(head,-1,sizeof(head));
memset(dis,0,sizeof(dis));
now=-1;
int a,b;double c,d,e,f;
for(int i=0;i<m;i++){
cin>>a>>b>>c>>d>>e>>f;
add(a,b,c,d);
add(b,a,e,f);
}
if(spfa()) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}