poj1860_类似负权回路
题意:有多种汇币,汇币之间可以交换,这需要手续费,当你用100A币交换B币时,A到B的汇率是29.75,手续费是0.39,那么你可以得到(100 - 0.39) * 29.75 = 2963.3975 B币。问s币的金额经过交换最终得到的s币金额数能否增加。
分析:这个题跟2240基本相似。也是利用bellman或者spfa进行松弛。细节也有不同,这个题指定了起始点。
代码:
View Code
1 #include <iostream> 2 #include <stdio.h> 3 #include <cstring> 4 using namespace std; 5 //172K 16MS 6 const int maxp=101; 7 const int maxe=202; 8 struct edge 9 { 10 int u,v; 11 double r,c; 12 }edge[maxe]; 13 double value[maxp]; 14 int n,m,s,index; 15 double v; 16 17 void Init() 18 { 19 int i; 20 for(i=1;i<=n;i++) 21 value[i]=-1.0; 22 int u,v; 23 double r1,c1,r2,c2; 24 index=1; 25 for(i=1;i<=m;i++) 26 { 27 scanf("%d%d%lf%lf%lf%lf",&u,&v,&r1,&c1,&r2,&c2); 28 edge[index].u=u; 29 edge[index].v=v; 30 edge[index].r=r1; 31 edge[index].c=c1; 32 index++; 33 edge[index].u=v; 34 edge[index].v=u; 35 edge[index].r=r2; 36 edge[index].c=c2; 37 index++; 38 } 39 } 40 41 bool bellman(int u,double w) 42 { 43 value[u]=w; 44 int i,j; 45 bool flag; 46 for(i=1;i<=n;i++) 47 { 48 flag=false; 49 for(j=1;j<index;j++) 50 { 51 int u=edge[j].u; 52 int v=edge[j].v; 53 if(value[v]<(value[u]-edge[j].c)*edge[j].r) 54 { 55 flag=true; 56 value[v]=(value[u]-edge[j].c)*edge[j].r; 57 } 58 } 59 if(!flag) 60 break; 61 } 62 return flag; 63 } 64 65 int main() 66 { 67 scanf("%d%d%d%lf",&n,&m,&s,&v); 68 Init(); 69 if(bellman(s,v)) 70 printf("YES\n"); 71 else 72 printf("NO\n"); 73 return 0; 74 }