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 }