题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=66569#problem/E
题意:给定N个货币转换点,以及转换的汇率和手续费,问是否可以经过如干转换后,使当前的货币数量增加。英语太渣,看了别人的题解才懂的。
思路:我也不知道什么方法,只知道这题是要判断正环的存在,因为只要正环存在,就能够沿着这个正环无限走下去,是货币增加的无限量,至于能否回到起点,显然是肯定的,因为给定的是双向路!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int N,M,S,vis[110],cnt[110],Map[110][110];
double V,R[110][110],C[110][110],num[110];
double eps=1e-10;//double的相等标志
void bfs(){
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
memset(num,0,sizeof(num));//把每个点才初始货币数量设为0
queue<int> Q;
Q.push(S);vis[S]=1;num[S]=V;cnt[S]++;
while(!Q.empty()){
int tp=Q.front();Q.pop();vis[tp]=0;
if(cnt[tp]>=N) {cout<<"YES\n";return;}//环存在标志
for(int i=1;i<=N;i++) if(i!=tp && Map[tp][i]){
double t=(num[tp]-C[tp][i])*R[tp][i];
if(t-num[i]<eps) continue;//不能使i的数量增加
num[i]=t;
if(!vis[i]) vis[i]=1,Q.push(i),cnt[i]++;
}
}
cout<<"NO\n";
}
int main(){
//freopen("D:\\in.txt","r",stdin);
while(cin>>N){
cin>>M>>S>>V;
int a,b;
memset(Map,0,sizeof(Map));
for(int i=0;i<M;i++){
scanf("%d %d",&a,&b);
scanf("%lf %lf %lf %lf",&R[a][b],&C[a][b],&R[b][a],&C[b][a]);
Map[a][b]=Map[b][a]=1;//a,b之间存在转换路径
}
bfs();
}
return 0;
}