Time Limit: 1000MS | Memory Limit: 30000K | |
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
题目大意:有n种货币,2*m种兑换关系,每次兑换需要支付c元手续费,汇率为r,初始有s货币v元,求是否能通过兑换,使持有的s货币变多?
由于本题是要求走一圈后,权值变大,所以更改Bellman-Ford的初始条件和更新条件,即可更改为求已s为起点的“最长路”,因为更新方法变了,所以每次能更新到的点必定是s点可达的点,即也再可兑换回s,所以只要用Bellman-Ford判断是否有“负权回路”即可
关于讨论版后的数据:
45 43 8 32.460000 40 6 90.90 17.59 45.28 89.70 29 18 37.97 55.13 84.48 52.81 45 26 59.25 99.43 27.79 90.84 7 42 57.94 54.76 90.96 64.60 27 12 18.69 31.72 66.78 65.72 //5 31 4 48.09 14.86 56.63 18.38 23 1 96.51 39.40 14.79 23.51 22 25 85.68 78.28 77.54 0.17 18 5 28.25 56.09 2.81 25.39 34 42 91.34 9.29 34.51 99.34 20 32 39.35 63.72 58.26 19.53 36 34 1.79 61.68 23.29 4.84 30 12 70.83 5.46 4.05 31.37 //13 16 37 39.47 57.44 59.00 79.05 16 14 68.12 5.58 35.39 19.28 13 44 27.08 32.10 75.83 47.52 45 37 6.31 81.34 22.96 54.24 24 19 41.55 58.31 93.99 84.14 28 36 73.32 80.70 37.02 33.93 6 21 56.88 6.52 76.14 30.43 18 35 83.55 30.02 41.25 89.11 17 37 70.84 51.14 44.76 29.99 14 2 42.34 26.79 51.95 93.56 40 6 63.46 83.44 82.66 15.09 27 20 34.61 61.69 10.23 35.04 29 13 83.62 38.65 88.51 27.75 30 22 59.09 3.86 63.35 57.85 4 18 11.24 97.52 8.80 11.15 38 42 79.71 33.62 3.36 36.53 38 45 90.65 72.52 18.35 54.58 33 45 16.35 58.44 57.71 88.69 1 43 84.41 35.96 72.06 27.57 13 9 46.36 94.47 81.63 88.19 42 10 41.22 1.63 98.33 85.94 9 3 40.00 49.78 46.31 86.28 11 37 27.72 17.84 56.89 86.23 45 10 99.57 92.25 71.49 1.57 8 14 19.47 82.06 32.79 90.53 23 37 26.54 38.20 99.18 86.79 10 42 98.34 36.13 88.52 98.24 13 30 85.81 43.84 54.64 33.83 31 8 53.55 51.02 46.20 87.65 30 8 92.31 36.44 91.82 23.12 //43
#include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int MAXN=105; const int INF=0x3f3f3f3f; struct Edge { int s,e; double r,c; Edge(int ss=0,int ee=0,double rr=0,double cc=0):s(ss),e(ee),r(rr),c(cc) {} }; int n,m,a,b; double s,v,r1,c1,r2,c2; vector<Edge> edge; double dis[MAXN]; bool Bellman_Ford(int sta) {//可判断负权回路 bool relaxed; memset(dis,0,sizeof(dis)); dis[sta]=v;//初始化sta货币有v,其余均为0 for(int i=1;i<n;++i) { relaxed=false; for(int j=0;j<edge.size();++j) { if((dis[edge[j].s]-edge[j].c)*edge[j].r>dis[edge[j].e]) {//松弛,只有兑换后当前币种的货币数量上升时才更新 dis[edge[j].e]=(dis[edge[j].s]-edge[j].c)*edge[j].r; relaxed=true; } } if(!relaxed) {//如果未更新,则不会再更新,且无负权回路 return false; } } for(int j=0;j<edge.size();++j) { if((dis[edge[j].s]-edge[j].c)*edge[j].r>dis[edge[j].e]) {//如果可以继续松弛,则存在负权回路 return true; } } return false; } int main() { while(4==scanf("%d%d%lf%lf",&n,&m,&s,&v)) { edge.clear(); while(m-->0) { scanf("%d%d%lf%lf%lf%lf",&a,&b,&r1,&c1,&r2,&c2); edge.push_back(Edge(a,b,r1,c1)); edge.push_back(Edge(b,a,r2,c2)); } printf("%s\n",Bellman_Ford(s)?"YES":"NO"); } return 0; }