题意
有多种汇币,汇币之间可以交换,这需要手续费,当你用100A币交换B币时,A到B的汇率是29.75,手续费是0.39,那么你可以得到(100 - 0.39) * 29.75 = 2963.3975 B币。问s币的金额经过交换最终得到的s币金额数能否增加 货币的交换是可以重复多次的,所以我们需要找出是否存在正权回路,且最后得到的s金额是增加的 怎么找正权回路呢?(正权回路:在这一回路上,顶点的权值能不断增加即能一直进行松弛)
Sample Input
3 2 1 20.0 1 2 1.00 1.00 1.00 1.00 2 3 1.10 1.00 1.10 1.00
Sample Output
YES
对SPFA算法进行改造,原来的dis改为存的货币的数量,改为求最长路,如果有自环,那么dis会不断增加没有上限
if(money[v]<(money[u]-E[u][i].fee)*E[u][i].rate){ money[v]=(money[u]-E[u][i].fee)*E[u][i].rate; if(!vis[v])
#define _CRT_SBCURE_NO_DEPRECATE #include <set> #include <map> #include <cmath> #include <queue> #include <bitset> #include <stack> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #include <functional> #define ll long long #define mm0(a) memset(a,0,sizeof(a)) #define mm(a,b) memset(a,b,sizeof(a)) #define each(a,b,c) for(int a=b;a<=c;a++) #define de(x) cout << #x << " " << (x) <<endl //#define de(x) cout <<"" #define rush() int T;scanf("%d",&T);each(kase,1,T) #define scan(a,b) scanf("%d%d",&a,&b) #define fin(a) scanf("%d",&a) using namespace std; const int maxn = 1e3+5; const int INF = 0x3f3f3f3f; inline int read(){int s=0;char ch=getchar();for(; ch<'0'||ch>'9'; ch=getchar());for(; ch>='0'&&ch<='9'; ch=getchar())s=s*10+ch-'0';return s;} /* 3 2 1 20.0 1 2 1.00 1.00 1.00 1.00 2 3 1.10 1.00 1.10 1.00 */ struct Edge{ int v; double fee; double rate; Edge(int _v,double _fee,double _rate):v(_v),fee(_fee),rate(_rate){} }; vector<Edge>E[maxn]; void addEdge(int u,int v,double fee,double rate) { E[u].push_back(Edge(v,fee,rate)); } bool vis[maxn]; int cnt[maxn]; double money[maxn]; int n; int m; int start; double init_money; bool SPFA(int start,double init_money,int n) { memset(vis,false,sizeof(vis));//清空vis for(int i=1;i<=n;i++)money[i]=0; vis[start]=true; money[start]=init_money; queue<int>Q; while(!Q.empty())Q.pop(); Q.push(start); memset(cnt,0,sizeof(cnt)); cnt[start]=1; while(!Q.empty()) { int u=Q.front(); Q.pop(); vis[u]=false; for(int i=0;i<E[u].size();i++) { int v=E[u][i].v; if(money[v]<(money[u]-E[u][i].fee)*E[u][i].rate){ money[v]=(money[u]-E[u][i].fee)*E[u][i].rate; if(!vis[v]) { vis[v]=true; Q.push(v); if(++cnt[v]>n)return false; } } } } return true; } int main() { scanf("%d%d%d%lf",&n,&m,&start,&init_money); each(i,1,m) { int a,b; double rab,cab,rba,cba; scan(a,b); scanf("%lf%lf%lf%lf",&rab,&cab,&rba,&cba); addEdge(a,b,cab,rab); addEdge(b,a,cba,rba); } if(!SPFA(start,init_money,n)) cout<<"YES"<<endl; else cout<<"NO"<<endl; }