对应POJ题目:点击打开链接
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 20814 | Accepted: 7451 |
Description
Input
Output
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
Source
题意:有若干种货币,某些币种之间可兑换,给出各种兑换时的汇率r和手续费c,任何兑换都是双向的,但是两个方向的汇率和手续费可能不同,并告知你现在拥有的货币种类s(只拥有一种)及数量v,问是否可以通过货币建兑换最后回到本币种后钱数有所增加。
A->B (s-c)*r
思路:Bellman_Ford求最长路径,判断是否存在正权回路,是则输出YES,或者spfa求最长路径,用个in[i]数组判断点i入队次数是否大于n, 是则输出YES
Bellman_Ford:
#include<cstdio> #include<cstdlib> #include<cmath> #include<map> #include<queue> #include<stack> #include<vector> #include<algorithm> #include<cstring> #include<string> #include<iostream> const int MAXN=10000+10; const int INF=1<<30; using namespace std; double dis[105]; struct Edge { int u,v; double r,c; }E[MAXN]; bool Bellman_Ford(int s, int n, double v, int size) { for(int i=1; i<=n; i++) dis[i]=0.0; dis[s] = v; for(int i=1; i<=n-1; i++){ for(int j=0; j<size; j++){ if((dis[E[j].u] - E[j].c) * E[j].r > dis[E[j].v]) dis[E[j].v] = (dis[E[j].u] - E[j].c) * E[j].r; } } for(int i=0; i<size; i++){ if((dis[E[i].u] - E[i].c) * E[i].r > dis[E[i].v]) return true; } return false; } int main() { //freopen("in.txt","r",stdin); int n,m,s; double v; int size = 0 ; scanf("%d%d%d%lf", &n,&m,&s,&v); for(int i=0; i<m; i++){ int u,v; double r,c; scanf("%d%d%lf%lf", &u,&v,&r,&c); E[size].u = u; E[size].v = v; E[size].r = r; E[size++].c = c; scanf("%lf%lf", &r,&c); E[size].u = v; E[size].v = u; E[size].r = r; E[size++].c = c; } bool ok = Bellman_Ford(s,n,v,size); if(ok) printf("YES\n"); else printf("NO\n"); return 0; }
#include<cstdio> #include<cstdlib> #include<cmath> #include<map> #include<queue> #include<stack> #include<vector> #include<algorithm> #include<cstring> #include<string> #include<iostream> const int MAXN=10000+10; const int INF=1<<30; using namespace std; double dis[105]; int head[105]; int vis[105]; int in[105]; struct Edge { int v,next; double r,c; }E[MAXN]; bool spfa(int s, int n, double v) { for(int i=1; i<=n; i++) dis[i] = 0.0; dis[s] = v; queue<int>q; q.push(s); vis[s] = 1; in[s]++; while(!q.empty()) { int u=q.front(); q.pop(); vis[u] = 0; for(int i=head[u]; i!=-1; i=E[i].next){ int v = E[i].v; if((dis[u] - E[i].c) * E[i].r > dis[v]){ dis[v] = (dis[u] - E[i].c) * E[i].r; if(!vis[v]){ vis[v] = 1; in[v]++; if(in[v] > n) return true; q.push(v); } } } if(dis[s] > v) return true; } return false; } int main() { //freopen("in.txt","r",stdin); int n,m,s; double v; int size = 0 ; scanf("%d%d%d%lf", &n,&m,&s,&v); memset(head, -1, sizeof(head)); for(int i=0; i<m; i++){ int u,v; double r,c; scanf("%d%d%lf%lf", &u,&v,&r,&c); E[size].v = v; E[size].r = r; E[size].c = c; E[size].next = head[u]; head[u] = size++ ; scanf("%lf%lf", &r,&c); E[size].v = u; E[size].r = r; E[size].c = c; E[size].next = head[v]; head[v] = size++; } bool ok = spfa(s,n,v); if(ok) printf("YES\n"); else printf("NO\n"); return 0; }