POJ 2240 Arbitrage 【Floyd判正环+自环坑】

POJ 2240 Arbitrage

题目链接:vjudge传送门

题目大意:
给定货币种数及各自名称,及其给定某两种货币之间的转化比率(相乘即可)
问是否存在一种货币套现的方法,即有某种货币,经过货币之间的转换使得,其数额是原来的i倍,i>1

具体思路:
不得不说,这题真是垃圾题。坑人
先说一下思路,判断正环的问题,因为不是单一源点,所以不选择spfa,而选用用floyd判断正环
状态转移:maps[i][j] = max(maps[i][k] * maps[k][j],maps[i][j]);
坑人的地方就是居然会有自回路,你说弄个非连通图可以理解,居然搞个自环图
你见过RMB可以兑换RMB的吗,还是兑换比率大于1的那种,居然有人愿意钱多换钱少,题意简直反人类,贡献了10次WA

具体代码:

#include
#include
#include
#include
#include
#define eps 1e-8
using namespace std;
const int N = 35;

double maps[N][N];
string cur[N];
int n, m;

void init()
{
     
	//初始化表示不能转化,0表示不能转换,1表示一开始就是本身1比1
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			maps[i][j] = (i == j) ? 1 : 0; 	//有些题解把不能转换初始化为无穷大,用的还是裸的floyd模板,但是居然还能ac
}
bool floyd()
{
     

	for (int k = 1; k <= n; k++)	//floyd算法
		for (int i = 1; i <= n; i++)
		{
     
			for (int j = 1; j <= n; j++)
			{
     
				//个人认为如果初始化为INF,应该加上这句判断一下,但不知为何不加也能ac
				//if (maps[i][k] != INF && maps[k][j] != INF )	
					if (maps[i][j] < maps[i][k] * maps[k][j])	//初始化为0的好处,只要一个为0,相乘就为0,if语句一定不成立
						maps[i][j] = maps[i][k] * maps[k][j];
			}
			if (maps[i][i] -1 > eps)return true;	//存在一个正环即退出
		}
	return false;
}

int main()
{
     
	int cnt = 1;
	while (cin >> n, n)
	{
     
		int flag = 0;
		init();
		for (int i = 1; i <= n; i++)
			cin >> cur[i];
		cin >> m;
		for (int i = 1; i <= m; i++)
		{
     
			int s, d;
			string src, des;
			double rate;
			cin >> src >> rate >> des;
			if (src == des ) {
     	//坑人的地方,存在自身兑换自身的货币,因为没有用map存还没判断,所以WA了好几次
				if (rate - eps > 1) {
     	//自己能越兑换越增值,就之间退出循环
					flag = 1;
					break;
				}
				else continue;	//否则就是贬值或者不变,直接进入下一轮循环
			}
			for (int j = 1; j <= n; j++)
			{
     
				if (cur[j] == src)s = j;
				else if (cur[j] == des)
					d = j;
			}
			maps[s][d] = rate;
		}
		if(flag || floyd())cout<<"Case "<<cnt<<": Yes"<<endl;
		else cout << "Case " << cnt << ": No" << endl;
		cnt++;
	}
	return 0;
}

你可能感兴趣的:(最短路,OJ题解)