*12-【20分】D. 货币套汇(图路径)-

12-图连通与最小生成树-
题目描述
套汇是指利用货币汇兑率的差异将一个单位的某种货币转换为大于一个单位的同种货币。例如,假定1 美元可以买0.7 英镑,1 英镑可以买9.5 法郎,1法郎可以买到0.16美元。通过货币兑换,一个商人可以从1 美元开始买入,得到0.7×9.5×0.16=1.064美元,从而获得6.4%的利润。 给定n种货币c1 ,c2 ,… ,cn的有关兑换率,试设计一个有效算法,确定货币间是否存在套汇的可能性。

提示:判断图上是否出现正环,即环上所有的边相乘大于1

输入
第一行:测试数据组数

每组测试数据格式为:

第一行:正整数n (1< =n< =30),正整数m,分别表示n种货币和m种不同的货币兑换率。

2~n+1行,n种货币的名称。

n+2~n+m+1行,每行有3 个数据项ci,rij 和cj ,表示货币ci 和cj的兑换率为 rij。

输出
对每组测试数据,如果存在套汇的可能则输出YES

如果不存在套汇的可能,则输出NO。

输入样例
2
3 3
USDollar
BritishPound
FrenchFranc
USDollar 0.5 BritishPound
BritishPound 10.0 FrenchFranc
FrenchFranc 0.21 USDollar
3 6
USDollar
BritishPound
FrenchFranc
USDollar 0.5 BritishPound
USDollar 4.9 FrenchFranc
BritishPound 10.0 FrenchFranc
BritishPound 1.99 USDollar
FrenchFranc 0.09 BritishPound
FrenchFranc 0.19 USDollar

输出样例
YES
NO

#include<iostream>
 using namespace std;

 class Map
 {
 private:
     double martrix[100][100];
     string node[100];
     int nodenum;
     int arcnum;
     int cnum;
     double value;
     int flag;
     int visited[100];
     
     void DFS(int v)
     {
         int w,i,k;
         if(visited[v]==0)
             visited[v]=1;
         
         int *adjvex=new int[nodenum];
         for(i=0;i<nodenum;i++)
             adjvex[i]=-1;
         
         k=0;
         for(i=0;i<nodenum;i++)
         {
             if(martrix[v][i]!=0)
             {
                 adjvex[k]=i;
                 k++;
             }
         }
         
         i=0;
         for(w=adjvex[0];w!=-1;w=adjvex[i])
         {
             if(visited[w]==0)
             {
                 value=value*martrix[v][w];
                 DFS(w);
             }
             else if (visited[w]==2)
             {
                 double tvalue=value;
                 tvalue*=martrix[v][w];
                 
                 if(tvalue>1)
                     flag=1;
             }
             i++;
         }
         delete [] adjvex;
     }
     
 public:
     Map(int n)//初始化
     {
         nodenum=n;
         cnum=0;flag=0;
     }
     
     int getindex(string s)//得到名字编号
     {
         int i;
         for(i=0;i<nodenum;i++)
         {
             if(node[i]==s)
                 return i;
         }
         return -1;
     }
     
     void getmartrix()
     {
         int i,j;
         for(i=0;i<nodenum;i++)//初始化
             for(j=0;j<nodenum;j++)
                 martrix[i][j]=0;
         
         cin>>arcnum;
         for(i=0;i<nodenum;i++)
         {
             string s1;
             cin>>s1;
             node[i]=s1;
         }
         for(i=0;i<arcnum;i++)
         {
             string s1,s2;
             double currency;
             int index1,index2;
             
             cin>>s1>>currency>>s2;
             index1=getindex(s1);
             index2=getindex(s2);
             
             martrix[index1][index2]=currency;
         }
     }
     
     void DFSfind()
     {
         int v,k,i;
         
         for(k=0;k<nodenum;k++)
         {
             int sum=0;
             value=1;v=k;
             
             for(i=0;i<nodenum;i++)
             {
                 if(i==v)
                     visited[i]=2;
                 else
                     visited[i]=0;
             }
             
             do
             {
                 if(visited[v]==0||visited[v]==2)
                 {
                     sum++;
                     if(sum>1)
                         break;
                     DFS(v);
                 }
                 v=(v+1)%nodenum;
             }while(v!=k);
         }
         
         if(flag==1)
             cout<<"YES";
         else
             cout<<"NO";
         cout<<endl;
     }
 };

 int main()
 {
     int t;
     cin>>t;
     while(t--)
     {
         int n;
         cin>>n;
         Map m(n);
         m.getmartrix();
         m.DFSfind();
     }
 }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值