北大2240题

来源:互联网 发布:守望先锋网络初始化失 编辑:程序博客网 时间:2024/05/16 15:08

 题目链接:http://acm.pku.edu.cn/JudgeOnline/problem?id=2240

1,这道题与其说是Floyd的变形,不如说是动态规划的具体应用,因为Floyd的算法思想也是动态规划

2,这道题的最优子结构分析:

a)设A是一个n*n的矩阵,A[i][j]!=0当且仅当货币i到j有兑率,规定A[i][i] =1即自身到自身的兑率为1

b)Ak[i][j]代表从i到j中间插入不超过k个点的最大兑率,k=0时A0[i][j] = A[i][j]这就是动态规划的边界条件

      Ak[i][j] = max{Ak-1[i][m]*Ak-1[m][j]}(m = 0,1,2……n-1)即Ak[i][j]可以通过Ak-1[i][j]a求出来,这就是动态规划的重叠子问题

       性质和最优子结构性质。

3,最后检测对角线有没有大于1的就可以了

#pragma warning(disable:4786)

#include <iostream>
#include <string>
#include <map>
using namespace std;

#define MAX 30

struct Graph
{
 double arc[MAX][MAX];
 int v_num;
 int e_num;
};

int main()
{
 freopen("in.txt","r",stdin);
 map<string,int> mp;
 string name,bg,ed;
 int i,j,k,t;
 double tmp;
 Graph g;
 bool find;
 t = 1;
 while(cin >> g.v_num && g.v_num != 0)
 {
  for(i = 0;i < g.v_num;++i)
  {
   cin >> name;
   mp[name] = i;
  }

  for(i = 0;i < g.v_num;++i)
  {
   for(j = 0;j < g.v_num;++j)
    g.arc[i][j] = 0;
   g.arc[i][i] = 1;
  }

  cin >> g.e_num;
  for(i = 0;i < g.e_num;++i)
  {
   cin >> bg;
   cin >> tmp;
   cin >> ed;

   g.arc[mp[bg]][mp[ed]] = tmp;
  }

  for(k = 0;k < g.v_num;++k)
  {
   for(i = 0;i < g.v_num;++i)
   {
    for(j = 0;j < g.v_num;++j)
    {
     tmp = g.arc[i][k] * g.arc[k][j];
     if(tmp > g.arc[i][j])
      g.arc[i][j] = tmp;
    }
   }
  }

  cout << "Case " << t++ << ": ";
  find = false;
  for(i = 0;i < g.v_num;++i)
  {
   if(g.arc[i][i] > 1)
   {
    cout << "Yes" << endl;
    find = true;
    break;
   }
  }
  if(!find)
   cout << "No" << endl;
 }
 return 0;
}

原创粉丝点击