题意:有多个银行可以换钱,每个银行可以将特定的两种钱相互兑换,并且有自己的汇率,现在问是否可以将自己的钱通过银行兑换增加。

其实比较水,主要就是知道最短路问题里的负环可以通过bellman-fold或spfa判断出来,在这里其实就是找正的环就行了。

一开始WA了无数发……原因是传参传了int,但其实是double……

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<queue>
 4 using namespace std;
 5 
 6 int head[1005],point[2005],next[2005],size,t[2005],n,m;
 7 double r[2005],c[2005],dist[1005];
 8 bool vis[1005];
 9 
10 void add(int a,int b,double r1,double c1){
11     point[size]=b;
12     r[size]=r1;
13     c[size]=c1;
14     next[size]=head[a];
15     head[a]=size++;
16 }
17 
18 void spfa(int s,double v){
19     int i;
20     memset(dist,0,sizeof(dist));
21     memset(vis,0,sizeof(vis));
22     memset(t,0,sizeof(t));
23     dist[s]=v;
24     queue<int>q;
25     q.push(s);
26     vis[s]=1;
27     bool f=0;
28     while(!q.empty()){
29         if(f)break;
30         int u=q.front();
31         q.pop();
32         vis[u]=0;
33         for(i=head[u];~i;i=next[i]){
34             int j=point[i];
35             if(dist[j]<(dist[u]-c[i])*r[i]){
36                 dist[j]=(dist[u]-c[i])*r[i];
37                 if(!vis[j]){
38                     q.push(j);
39                     vis[j]=1;
40                     t[j]++;
41                     if(t[j]>n)f=1;
42                 }
43             }
44         }
45     }
46     if(f)printf("YES\n");
47     else printf("NO\n");
48 }
49 
50 int main(){
51     int s,i;
52     double v;
53     while(scanf("%d%d%d%lf",&n,&m,&s,&v)!=EOF){
54         memset(head,-1,sizeof(head));
55         size=0;
56         for(i=1;i<=m;i++){
57             int a,b;
58             double r1,c1;
59             scanf("%d%d%lf%lf",&a,&b,&r1,&c1);
60             add(a,b,r1,c1);
61             scanf("%lf%lf",&r1,&c1);
62             add(b,a,r1,c1);
63         }
64         spfa(s,v);
65     }
66     return 0;
67 }
View Code