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;
}