【动态规划DP,floyd最短路】poj2240,Arbitrage

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


钱币来回兑换。

大家都知道先构图,然后看图中的某个节点会不会经过一圈之后到达自己,并且路径上的权值乘积大于1。

显然是最短路的反面,最长路;同时不能使用单源最短路dijkstra算法。

所以使用floyd多源最短路,不过这里注意比较条件,要“最长路”。


从任意节点i到任意节点j的最短路径不外乎2种可能,1是直接从i到j,2是从i经过若干个节点k到j。所以,我们假设Dis(i,j)为节点u到节点v的最短路径的距离,对于每一个节点k,我们检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,证明从i到k再到j的路径比i直接到j的路径短,我们便设置Dis(i,j) = Dis(i,k) + Dis(k,j),这样一来,当我们遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离。



# include<iostream>
# include<stdio.h>
# include<string.h>
# include<string>
# include<map>
using namespace std;

# define N 40

map<string, int> mp;
double data[N][N];

int main()
{
	int n,m,i,j,k,c;	
	double rate;
	string c1,c2;
	
	c=0;
	//while(~scanf("%d",&n))=========逗了。。。
	while(true)
	{
		cin>>n;
		if(n==0)
		{
			break;
		}
		mp.clear();
		memset(data,0.0,sizeof(data));

		for(i=1;i<=n;i++)
		{
			cin>>c1;
			mp[c1]=i;
			data[i][i]=1.0;
		}

		cin>>m;
		for(i=1;i<=m;i++)
		{
			cin >> c1 >> rate >> c2;
			if(rate>data[mp[c1]][mp[c2]])
			{
				data[mp[c1]][mp[c2]]=rate;
			}
		}
		for(i=1;i<=n;i++)
		{
			for(j=1; j<=n;j++)
			{
				for(k=1;k<=n;k++)
				{
					if (data[i][j] < data[i][k]*data[k][j]) //find max path
					{
						data[i][j] = data[i][k]*data[k][j];//max path length
					}
				}
			}
		}
		

		j=0;
        for(i=1;i<=n;i++)
        {
            if(data[i][i]>1.0)//profit
            {
                j=1;
                break;
            }
        }
        if(j==1)
		{
			cout<<"Case "<<++c<<": Yes"<<endl;
		}
        else
		{
			cout<<"Case "<<++c<<": No"<<endl;
		}
	}
	

	return 0;
}


这里有个关于dijkstra算法和floyd算法的介绍,很不错:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html

你可能感兴趣的:(Arbitrage,Floyd最短路,动态规划DP,poj2240)