59519751 发表于 2017-7-2 09:20:24

POJ——T1860 Currency Exchange

  http://poj.org/problem?id=1860




Time Limit: 1000MS

Memory Limit: 30000K


Total Submissions: 29874

Accepted: 11251





  题目大意:




´有多种汇币,汇币之间可以交换,这需要手续费,当你用100A币交换B币时,A到B的汇率是29.75,手续费是0.39,那么你可以得到(100 - 0.39) * 29.75 = 2963.3975 B币。问s币的金额经过交换最终得到的s币金额数能否增加。



题解:



´货币的交换是可以重复多次的,所以我们需要找出是否存在正权回路,且最后得到的s金额是增加的。

所以用SPFA求正环就可以了



DFS求环法:




1 #include <cstring>
2 #include <cstdio>
3
4 #define dou double
5 #define INF 1<<29
6 #define MAX(a,b) ( a>b ?a :b )
7
8 using namespace std;
9
10 const int N(10015);
11 int n,m,s,u,v;
12 dou money,uvr,uvl,vur,vul;
13 int head,sumedge;
14 struct Edge
15 {
16   int to,next;
17   dou rate,lose;
18   Edge(int to=0,int next=0,dou rate=0.00,dou lose=0.00) :
19         to(to),next(next),rate(rate),lose(lose) {}
20 }edge;
21
22 void ins(int from,int to,dou rate,dou lose)
23 {
24   edge[++sumedge]=Edge(to,head,rate,lose);
25   head=sumedge;
26 }
27
28 dou change_money(dou x,dou rate,dou lose)
29 {   return (x-lose)*rate ;    }
30
31 int vis,if_YES;
32 dou dis;
33
34 void SPFA(int now)
35 {
36   vis=1;
37   if(if_YES) return ;
38   for(int i=head;i;i=edge.next)
39   {
40         int go=edge.to;
41         dou rate=edge.rate,lose=edge.lose;
42         dou cmoney=change_money(dis,rate,lose);
43         if(cmoney>dis)
44         {
45             if(vis)
46             {
47               if_YES=true;
48               break ;
49             }
50             dis=cmoney;
51             SPFA(go);
52         }
53   }
54   vis=0;
55   return ;
56 }
57
58 void init(int n)
59 {
60   if_YES=sumedge=0;
61   memset(dis,0,sizeof(dis));
62   memset(head,0,sizeof(head));
63 }
64
65 int main()
66 {
67 //    freopen("made.txt","r",stdin);
68 //    freopen("myout.txt","w",stdout);
69   
70   while(~scanf("%d%d%d%lf",&n,&m,&s,&money))
71   {
72         if(s>n)
73         {
74             printf("NO\n");
75             continue;
76         }
77         init(n);
78         for(;m;m--)
79         {
80             scanf("%d%d%lf%lf%lf%lf",&u,&v,&uvr,&uvl,&vur,&vul);
81             ins(u,v,uvr,uvl); ins(v,u,vur,vul);
82         }
83         dis=money; SPFA(s);
84         if(if_YES) printf("YES\n");
85         else printf("NO\n");
86   }
87   return 0;
88 }
  BFS求环法:





1 #include<cstdio>
2 #include<cstring>
3 #include<iostream>
4 #include<algorithm>
5 #include<queue>
6 using namespace std;
7 int u,v,w;
8 const int maxn = 1011;
9 const int maxm = 10011;
10 const int oo = 1<<29;
11 struct node
12 {
13   int u;
14   int v;
15   double x,y ;
16   int next;
17 }edge;
18 double dis;
19 int m,n,num;
20 double ount;
21 int head,cnt,sum;
22 int vis = {0};
23 queue<int>qu;
24 void add(int u,int v,double x,double y)
25 {
26   edge.u = u ;
27   edge.v = v ;
28   edge.x = x ;
29   edge.y = y ;
30   edge.next = head;
31   head = cnt++ ;
32 }
33 int spfa(int s)
34 {
35   for(int i = 0 ; i < m ; i++)
36   {
37         dis = 0;
38         vis = 0 ;
39   }
40   dis = ount;
41   qu.push(s);
42   vis = 1 ;
43   while(!qu.empty())
44   {
45         int u = qu.front();
46         qu.pop();
47         vis = 0;
48         for(int i = head ; i != -1 ; i = edge.next)
49         {
50             int v = edge.v;
51             if((dis-edge.y)*edge.x > dis)
52             {
53               dis = (dis-edge.y)*edge.x;
54               if(!vis)
55               {
56                     vis = 1;
57                     qu.push(v);
58               }
59               sum++;
60               if(sum > m)
61               return -1;
62             }
63         }
64   }
65   return 1;
66 }
67 void Init()
68 {
69   cnt = 0 ;
70   memset(head,-1,sizeof(head));
71   memset(sum,0,sizeof(sum));
72   while(!qu.empty())
73   qu.pop();
74 }
75 int main()
76 {
77   freopen("made.txt","r",stdin);
78   freopen("stdout.txt","w",stdout);
79   
80   while(scanf("%d %d %d %lf",&m,&n,&num,&ount)!=EOF)
81   {
82         Init();
83         int u,v;
84         double x,y,xx,yy ;
85         for(int i = 0 ; i < n ; i++)
86         {
87             scanf("%d %d %lf %lf %lf %lf",&u,&v,&x,&y,&xx,&yy);
88             add(u,v,x,y);
89             add(v,u,xx,yy);
90         }
91         if(spfa(num) > 0)
92         cout<<"NO"<<endl;
93         else cout<<"YES"<<endl;
94   }
95   return 0;
96 }
页: [1]
查看完整版本: POJ——T1860 Currency Exchange