【floyed】【HDU1217】【Arbitrage】

题目大意:

给你几种货币,以及几种汇率关系,问是否存在套利的可能?


思路:

初步想法:图上存在一个环的路径上权值相乘大于1....


再者:该如何找到图上所有环呢....


好吧 经过鸟神 和 况神的指点,,,这题就是一道floyed求最小环而已(权重取负)(虽然差不多,其实还是差挺远..)


对于乘法处理转换为ln...Orz一下鸟神


Floyed求最小环(后来才发现没关系)


一开始天真的以为.....只要求一遍Floyed 再判断一下F[i][i]就好,但要记住这个图是带负权值的....所以可能是走过几圈的........


(但其实这个题没有影响,只需要判断最终的结果是否小于0即可,多走几圈,依旧会小于0。。事实上也A了..)

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#define oo 0x13131313
using namespace std;
const double e=2.718281828459;
const int    maxn=31;
double F[maxn][maxn];
map<string,int> money;
int n,m;                          //number of price

void Clear()
{
    for(int i=0;i<maxn;i++)
        for(int j=0;j<maxn;j++)
         F[i][j]=2100000000;
    money.clear();
}
double ans=2100000000;
void solve()
{
     ans=2100000000;
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
         for(int j=1;j<=n;j++)
    {
        if(F[i][k]+F[k][j]<F[i][j])
            F[i][j]=F[i][k]+F[k][j];
    }
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
    {
        if(F[i][k]+F[k][i]<F[i][i])
            F[i][i]=F[i][k]+F[k][i];
        if(F[i][i]<ans) ans=F[i][i];
    }

}
void input()
{
    string a,b;
    double c;
    for(int i=1;i<=n;i++)
    {
        cin>>a;
        money[a]=i;
    }
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        cin>>a>>c>>b;
        c=-log(c);
        F[money[a]][money[b]]=c;
    }
}
void init()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
}
int main()
{
   // init();
    int Case=0;
    while(cin>>n&&n)
    {
        Case++;
        printf("Case %d: ",Case);
        Clear();
        input();
        solve();
        if(ans<0) printf("Yes\n");
        else printf("No\n");
    }
}




即时这个题不需要。

但还是要搞懂怎么求最小环!!未完待续..。

带负权求不出


你可能感兴趣的:(【floyed】【HDU1217】【Arbitrage】)