标签:
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
题解:如果存在一个环使得钱增多了,说明肯定可行,因为可以无限兑换,而判断环用bellman和spfa可以判断。
bellman:
#include <iostream> #include <cstdio> #include <cstring> #define mem(a) memset(a,false,sizeof(a)); using namespace std; struct Node { int from; int to; double rate; double com; }; Node e[220]; double d[120]; bool bellman(double v,int s,int n,int edge) { for(int i = 1;i <= n;i++) //对所有的货币兑换初始化为0 { d[i] = 0; } d[s] = v; //d[i]表示初始时刻的s兑换的钱 bool flag; for(int i = 1;i <= n;i++) //n个点最短路最多有n-1条 { flag = false; for(int j = 0;j < edge;j++) { if(d[e[j].to] < (d[e[j].from] - e[j].com) * e[j].rate) //找到能兑换更多的方式,可能包含回路 { flag = true; d[e[j].to] = (d[e[j].from] - e[j].com) * e[j].rate; } } if(!flag) { return false; } if(i == n) { return true; } } // for(int i = 0;i < edge;i++) // { // if(d[e[i].to] < (d[e[i].from] - e[i].com) * e[i].rate) // { // return true; // } // } } int main() { int n,m,s; double v; while(scanf("%d%d%d%lf",&n,&m,&s,&v) != EOF) { int A,B; int k = 0; double rab,cab,rba,cba; for(int i = 0;i < m;i++) { scanf("%d%d%lf%lf%lf%lf",&A,&B,&rab,&cab,&rba,&cba); e[k].from = A; e[k].to = B; e[k].rate = rab; e[k++].com = cab; e[k].from = B; e[k].to = A; e[k].rate = rba; e[k++].com = cba; } if(bellman(v,s,n,k)) { printf("YES\n"); } else { printf("NO\n"); } } return 0; }
SPFA:
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #define mem(a) memset(a,0,sizeof(a)); using namespace std; struct Node { double rate; double com; }; bool inQueue[120]; //入队没有 int cnt[120]; //入队次数 Node map[120][120]; double d[120]; bool spfa(int n,int s,double v) { mem(cnt); mem(inQueue); for(int i = 1;i <= n;i++) { d[i] = 0; } d[s] = v; queue<int> q; q.push(s); inQueue[s] = true; cnt[s] = 1; while(!q.empty()) { int t = q.front(); q.pop(); inQueue[t] = false; for(int i = 1;i <= n;i++) { if(map[t][i].rate != 0.0) //与出队点能够兑换 { if(d[i] < (d[t] - map[t][i].com) * map[t][i].rate) //兑换了钱变多 { d[i] = (d[t] - map[t][i].com) * map[t][i].rate; if(!inQueue[i]) { q.push(i); inQueue[i] = true; } if(++cnt[i] == n) //入队次数达到了n次,说明存在环使得钱变多 (因为每次都更新) { return true; } } } } } return false; } int main() { int n,m,s; double v; while(scanf("%d%d%d%lf",&n,&m,&s,&v) != EOF) { int A,B; int k = 0; double rab,cab,rba,cba; for(int i = 1;i <= n;i++) { for(int j = 1;j <= n;j++) { map[i][j].rate = 0; } } for(int i = 0;i < m;i++) { scanf("%d%d%lf%lf%lf%lf",&A,&B,&rab,&cab,&rba,&cba); map[A][B].rate = rab; map[A][B].com = cab; map[B][A].rate = rba; map[B][A].com = cba; } if(spfa(n,s,v)) { printf("YES\n"); } else { printf("NO\n"); } } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/wang2534499/article/details/47682215