poj 2240 Floyd判断有向图负环(arbitrage)

来源:互联网 发布:ubuntu 命令行解压deb 编辑:程序博客网 时间:2024/06/08 14:04

题意:Arbitrage问题(套汇)。给定若干币种及一些币种转换的汇率,问能否有套汇的可能。

思路:如果以币种为定点,汇率为边建图,则相当于求一个圈,其上权值乘积大于1。将权值取对数再取负,变成求有向图负环。用floyd算法即可。(直接上Floyd,三层循环中判断直接用乘法也OK)。另外用spfa判断应该也行,只需将每个点都入队一次。

#include <stdio.h>#include <string.h>#include <math.h>#define min(a,b) ((a)<(b)?(a):(b))#define N 35char name[N][128];int c=1,n,m;double g[N][N];int find(char* x){    int i;    for(i = 1;i<=n;i++)        if(!strcmp(name[i], x))            return i;    return -1;}int main(){    while(scanf("%d",&n) && n){        int i,j,k,a,b;        char s[128],t[128];        double w;        for(i = 1;i<=n;i++)            for(j = 1;j<=n;j++)                g[i][j] = 0x3fffffff;        for(i = 1;i<=n;i++)            scanf("%s",name[i]);        scanf("%d",&m);        for(i = 0;i<m;i++){            scanf("%s %lf %s",s,&w,t);            a = find(s);            b = find(t);            g[a][b] = -log10(w);        }        for(k = 1;k<=n;k++)            for(i = 1;i<=n;i++)                for(j = 1;j<=n;j++)                    g[i][j] = min(g[i][j],g[i][k]+g[k][j]);        for(i = 1;i<=n;i++)            if(g[i][i] < 0)                break;        if(i<=n)            printf("Case %d: Yes\n",c++);        else            printf("Case %d: No\n",c++);    }    return 0;}


0 0
原创粉丝点击