hdu1217Arbitrage--解題報告

題意:套利,一個US幣換取0.5 British pound,而1 British pound 換取10.0 French francs,同時 1 French franc buys 0.21 US dollar. 那麼1 US dollar 可以換取 0.5 * 10.0 * 0.21 = 1.05 US dollars ,通過一系列換取得到1.05US幣,那麼就可以從中獲取利潤,問:給出一些貨幣,以及兌換率,問是否可以從中獲利

題解:這裏可以用最短路的方法解決:我們在邊的結構體 添加兌換率,然後鬆弛過程中,不同於最短路的取小,我們要讓它獲利就要取大,那麼我們在spfa之前的dis初始化的時候,我們就全部memset爲0,dis[src] 源點就賦值 1.這樣我們就可以按照上面的方式鬆弛操作,然後判斷是否構成負環。。如果可以,那麼意思就是dis 會越來越大,spfa 用cnt[i]表示 i 入隊的次數,i的入隊次數大於 頂點數就說明構成負環

上馬:

#include <iostream>
#include <map>
#include <string>
#include <cstring>
#include <queue>

using namespace std;

#define MAX 35

int N,M;

struct Edge{
    int to,next;
    double rate;
}edge[MAX*MAX];
int head[MAX];

void add(int u,int v,double rate,int i)
{
    edge[i].to = v;
    edge[i].rate = rate;
    edge[i].next = head[u];
    head[u] = i;
}

double dis[MAX];
int cnt[MAX];
bool flag[MAX];
bool spfa()
{
    memset(flag,false,sizeof(flag));
    memset(cnt,0,sizeof(cnt));
    memset(dis,0,sizeof(dis));

    dis[0] = 1;
    flag[0] = true;
    cnt[0] = 1;

    queue<int> q;
    q.push(0);

    while(!q.empty())
    {
        int u = q.front(); q.pop();
        flag[u] = false;
        for(int i = head[u]; i != -1; i = edge[i].next)
        {
            int v = edge[i].to;
            double rate = edge[i].rate;
            if(dis[v] < dis[u]*rate){
                dis[v] = dis[u]*rate;
                if(!flag[v]){
                    q.push(v);
                    flag[v] = true;
                    cnt[v] ++;
                }
            }
            if(cnt[v] > N) return true;
        }
    }
    return false;
}

int main()
{
    string a,b;
    double rate;
    int cas = 1;
    while(cin >> N)
    {
        if(!N) break;
        map<string,int>m;
        for(int i = 0; i < N; i ++) {
            cin >> a;
            m[a] = i;
        }
        cin >> M;
        memset(head,-1,sizeof(head));
        for(int i = 0; i < M; i ++){
            cin >> a >> rate >> b;
            int u = (*m.find(a)).second;
            int v = (*m.find(b)).second;
            add(u,v,rate,i);
        }

        cout << "Case " << cas++ << ": ";
        if(spfa()) cout << "Yes" <<endl;
        else cout << "No" <<endl;
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章