POJ 2240 Arbitrage Floyd || Bellman

题目大意:求货币经过与其他货币之间的兑换操作,能否使转化率大于一。

思路一:我们就可以想到用Floyd 的变形,通过Floyd求得到自身的最大路径,最大环。

细节处理:此题的输入为字符串输入,于是我们需要一个容器来使它达到与下标一一对应的效果,可以使用map<string,int>来完成。

代码如下:

#include<cstdio>
#include<cstring>
#include<map>
#include<iostream>
using namespace std;
double rate;
map<string,int> S;
int n,m;
char str[100],str1[100],str2[100];
double d[100][100];
int main()
{
	int CASE=1;
	while(scanf("%d",&n)&&n&&CASE)
	{
		for(int i=1;i<=n;i++)
		{
			cin>>str;
			S[str]=i;
			d[i][i]=1;	
		}
		 cin>>m;
		 for(int i=1;i<=m;i++)
		 {
			cin>>str1>>rate>>str2;
			d[S[str1]][S[str2]]=rate;		
		 }
		 for(int i=1;i<=n;i++)
		    for(int j=1;j<=n;j++)
		    	for(int k=1;k<=n;k++)
				{
					if(d[i][j]<d[i][k]*d[k][j])
					d[i][j]=d[i][k]*d[k][j];	
				}
		bool flag=false;
		for(int i=1;i<=n;i++)
			if(d[i][i]>1)
			{
				flag=true;	
				break;
			}
		if(flag)
			cout<<"Case "<<CASE++<<": "<<"Yes"<<endl;
		else 
			cout<<"Case "<<CASE++<<": "<<"No"<<endl;
	}	
	//while(1);
	return 0;
} 

思路二:此题也可以用最直接想到的Bellman进行求解

代码如下:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<map>
using namespace std;
map<string,int> S;
char str1[5000],str[5000],str2[5000];
double rate;
double d[5000];
int n,m;
struct lxt
{
	int a,b;
	double c;	
}edge[5000];	
bool Bellman(int s)//推荐每次都用单源求Bellman( )
{
	for(int i=1;i<=n;i++)
	d[i]=0.0;
	d[s]=1.0;
	bool flag=false;
	for(int k=1;k<=n;k++)//注意循环N次来判断是否能达到我们需要的大于1的汇率
	{
		flag=false;
		for(int i=1;i<=m;i++)
		{
			if(d[edge[i].a]&&d[edge[i].a]*edge[i].c>d[edge[i].b])
			{
				d[edge[i].b]=d[edge[i].a]*edge[i].c;	
			}
		}
	}
	if(d[s]>1.00)
			return true; 
	return false ;
}
int main()
{
	int Case=1;
	while(scanf("%d",&n)&&n)
	{
		S.clear();
		memset(edge,0,sizeof(edge));
		for(int i=1;i<=n;i++)
		{
			cin>>str;
			S[str]=i;	
		}
		cin>>m;
		for(int i=1;i<=m;i++)
		{
			cin>>str1>>rate>>str2;
			edge[i].a=S[str1];
			edge[i].b=S[str2];
			edge[i].c=rate;	
		}	
		bool flag=false;
		for(int i=1;i<=n;i++)
		{
			if(Bellman(i))
			{
				flag=true;
				break;	
			}	
		}
		if(flag)
			cout<<"Case "<<Case++<<": Yes"<<endl;
		else 
			cout<<"Case "<<Case++<<": No"<<endl;
	}
	//while(1);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值