POJ_2240_Arbitrage(Floyd 算法)

/*题意:求自身到自身的最大转换率。
最简单的方法就是floryd算法变形,求最大路径后,求最大环,看它是否满足条件。
每一个结点都必须有到自身的环(不甚清楚原因)
如果操作中含环的话,环记录的1,即代表原始钱数。操作完之后就改变成增值后的钱数。
如果操作中不含环,那么就跟平时的Floyd算法一样记录的是两个点之间最大的交换率。

*/

下面给出两种代码。

代码一:Floyd

 1 # include <stdio.h>
 2 # include <string.h>
 3 # define inf 10000
 4 double map[1005][1005];
 5 int n,m;
 6 void Floyd()
 7 {
 8     int i,j,k,flag=0;
 9     for(k=1;k<=n;k++)
10         for(i=1;i<=n;i++)//开始的时候想使用两层循环直接找即判断map[i][i]与map[i][k]map[k][j]
11                         //后来想了想是不行的,因为那样你只能访问到邻接的最优的是访问不到的。
12             for(j=1;j<=n;j++)
13                 if(map[i][j] < map[i][k]*map[k][j])
14                     map[i][j]=map[i][k]*map[k][j];
15                 for(i=1;i<=n;i++)
16                     if(map[i][i] > 1)
17                     {
18                         flag=1;
19                         break;
20                     }
21                     if(flag)
22                         printf("Yes\n");
23                     else
24                         printf("No\n");
25                     return ;
26 }
27 int main()
28 {
29     int i,j,k;
30     double c;
31     char ch[31][50];
32     char a[50],b[50];
33     int leag=0;
34     while(scanf("%d",&n)!=EOF)
35     {
36         memset(map,inf,sizeof(map));
37         if(!n)break;
38         for(i=0;i<n;i++)
39             scanf("%s",ch[i]);    
40         scanf("%d",&m);
41         getchar();
42         for(i=1;i<=m;i++)
43             map[i][i]=1;
44         for(i=1;i<=m;i++)
45         {
46             scanf("%s%lf%s",a,&c,b);
47             getchar();
48             for(j=0;j<n;j++)
49                 if(!strcmp(ch[j],a))
50                     break;
51             for(k=0;k<n;k++)
52                 if(!strcmp(ch[k],b))
53                     break;
54             map[j+1][k+1]=c;
55         }
56         printf("Case %d: ",++leag);
57         Floyd();
58     }
59     return 0;
60 }

 代码二:Bellman

 1 /*
 2 用Bellman算法来做跟1860 3259 题差不多,只不过注意他有自身与自身交换的情况
 3 a 1.1 a。在这里我使用的是邻接矩阵存储的,因此在判断的时候需要把不邻接的边过滤掉
 4 还有就是不进j->k.而且要考虑k->j的情况。如果改成结构体存储边的信息,像前面几道题,
 5 则不需要过滤。
 6 */
 7 #include <iostream>
 8 #include<map>
 9 #include<string>
10 using namespace std;
11 map<string,int>STL;
12 double edge[1005][1005];
13 double dis[100];
14 const int inf=10000;
15 int n,m;
16 //建立一个 使字符串与整数有一一对应关系 的容器STL,以便利用邻接矩阵存储数据   
17 int Bellman()
18 {
19     int j;
20     bool flag;
21     memset(dis,0,sizeof(dis));
22     dis[1]=1;
23     while(dis[1]<=1)
24     {
25         flag=false;
26         for(j=1;j<=n;j++)
27         {
28             for(int k=1;k<=n;k++)
29             {
30                 if( edge[j][k]<10000 && dis[k] < dis[j]*edge[j][k])
31                 {
32                     dis[k]=dis[j]*edge[j][k];
33                     flag=true;
34                 }
35                  if( edge[k][j]<10000 && dis[j] < dis[k]*edge[k][j])
36                 {
37                     dis[j]=dis[k]*edge[k][j];
38                     flag=true;
39                 }
40             }
41         }
42         if(!flag)
43             return dis[1]>1 ? 1:0;
44     }
45     return 1;
46     
47 }
48 int main()
49 {
50     int flag=0;
51     int i,j,k;
52     double rate;
53     char str1[50],str2[50],str[50];
54     while(scanf("%d",&n) != EOF)
55     {
56         getchar();
57         if(!n)break;
58         sizeof(edge,inf,sizeof(edge));
59         for(i=1;i<=n;i++)
60         {
61             scanf("%s",str);
62             STL[str]=i;
63             edge[i][i]=1;
64         }
65         scanf("%d",&m);
66         getchar();
67         for(i=1;i<=m;i++)
68         {
69             scanf("%s%lf%s",str1,&rate,str2);
70             edge[STL[str1]][STL[str2]]=rate;
71         }
72         printf("Case %d: ",++flag);
73         if(Bellman())
74             printf("Yes\n");
75         else
76             printf("No\n");
77     }
78     return 0;
79 }

 

posted on 2013-08-15 20:52  随风浪子的博客  阅读(167)  评论(0编辑  收藏  举报

导航