poj2240 Bellman_Ford

题目大意

给定n中货币,及m中汇率关系,问是否能实现套利。

解题思路

该题与poj1860类似,均可用Bellman_Ford的思想求解。
Bllman_Ford用于求解任意权值的单元最短路径,并判断图中是否包含有带负权值的回路。
类似地,对于该问题,可以理解为求最长路径问题,并判断图中是否有回路,若有则能实现套利,否则不能实现。利用Bellman_Ford求解该问题是松弛条件是与Bellman_Ford相反的。
Bellman_Ford算法步骤
给定图G(V, E)(其中V、E分别为图G的顶点集与边集),源点s
数组d[i]记录从源点s到顶点i的路径长度

Bellman_Ford(){
    初始化dist数组
    for i ← 1 to |V[G]| - 1 
        do for each edge (u, v) ∈ E[G] 
            do RELAX(u, v, w)
    for each edge (u, v) ∈ E[G] 
        do if d[v] > d[u] + w(u, v) 
            then return FALSE
    return TRUE
}

Bellman_Ford算法参考http://www.wutianqi.com/?p=1912

注意:因为m种汇率关系中可能包含从美元到美元的汇率关系这种情况。

代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 100
char curr[35][LEN];
double dist[35];
int n,m;
struct Edge{
    int u;
    int v;
    double rate;
};
struct Edge edge[1200];
int relax(int u,int v,double rate){
    double tmp = dist[u]*rate;
    if(dist[v]<tmp){
        dist[v] = tmp;
        return 1;
    }
    return 0;
}
int Bellman_Ford(){
    int i,j,k,tag;
    for(i=1;i<=n;i++)
        dist[i] = -1.0;
    dist[edge[1].u] = 1.0;
    for(k=1;k<n;k++){
        for(i=1;i<=m;i++)
            relax(edge[i].u,edge[i].v,edge[i].rate);
    }
    tag = 0;
    for(i=1;i<=m;i++){
        if(relax(edge[i].u,edge[i].v,edge[i].rate)){
            tag = 1;
            break;
        }
    }
    return tag;
}
int main()
{
    int i,j,k,tag,flag;
    double rate;
    char a[LEN],b[LEN];
    for(k=1;;k++){
        scanf("%d",&n);
        if(n==0)
            break;
        memset(curr,0,sizeof(curr));
        for(j=1;j<=n;j++){
            scanf("%s",curr[j]);
        }
        scanf("%d",&m);
        for(j=1;j<=m;j++){
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            scanf("%s %lf %s",a,&rate,b);
            flag = 0;
            for(i=1;i<=n;i++){
                if(strcmp(a,curr[i])==0){
                    edge[j].u = i;
                    flag++;
                }
                if(strcmp(b,curr[i])==0){ //a.不能使用else if
                    edge[j].v = i;
                    flag++;
                }
                if(flag==2)
                    break;
            }
            edge[j].rate = rate;
        }
        tag = Bellman_Ford();
        if(tag){
            printf("Case %d: Yes\n",k);
        }else{
            printf("Case %d: No\n",k);
        }
    }
    return 0;
}
    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/tiana_/article/details/70048867
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞