POJ 2240 Arbitrage 最短路 Floyd

题意:首先给出N中货币,然后给出了这N种货币之间的兑换的兑换率。如 USDollar 0.5 BritishPound 表示 :1 USDollar兑换成0.5 BritishPound。问在这N种货币中是否有货币可以经过若干次兑换后,兑换成原来的货币可以使货币量增加。 本题其实是FLOYD的变形。将变换率作为构成图的路径的权重。这儿构成的图是一个有向图。最后将松弛操作变换为:if(dis[i][j]<dis[i][k]*dis[k][j])。
import java.util.*;
public class Main {   
    static int c=0;   
    static String[] str;   
    static double[][] map;   
    static double[] v;   
    static int n,m;   
    static boolean[] visited;   
       
    public static void main(String[] args){   
        Main p=new Main();   
        Scanner cin=new Scanner(System.in);   
        while(true){   
            c++;   
            n=cin.nextInt();   
            if(n==0) return;   
            str=new String[n];   
            map=new double[n][n];   
            v=new double[n];   
            visited=new boolean[n];   
            for(int i=0;i< n;i++){   
                str[i]=cin.next();   
                map[i][i]=1;   
            }   
            m=cin.nextInt();   
            for(int i=0;i< m;i++){   
                String a=cin.next();   
                double r=cin.nextDouble();   
                String b=cin.next();   
                map[p.find(a)][p.find(b)]=r;   
                   
            }      
            p.solve();   
        }   
    }   
    void solve(){   
            floyd(map);   
            for(int i=0;i< n;i++){   
                if(map[i][i]>1){   
                    System.out.println("Case " + c +  ": Yes");   
                    return;   
                }   
            }   
            System.out.println("Case " + c +  ": No");   
    }   
    void floyd(double[][] map){   
        for(int k=0;k < n;k++)   
            for(int i=0;i< n;i++)   
                for(int j=0;j< n;j++)   
                    if(map[i][j]< map[i][k]*map[k][j])   
                        map[i][j]=map[i][k]*map[k][j];   
    }   
    int find(String a){   
        for(int i=0;i< n;i++)   
            if(a.equals(str[i]))   
                return i;   
        return 0;   
    }   
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值