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<iostream>
#include<cstdio>
#include<stdlib.h>
#include<algorithm>
#include<string>
#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;
}
發佈了69 篇原創文章 · 獲贊 34 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章