poj 1237 The Postal Worker Rings Once // hoj 1164 The Postal Worker Rings Once

题目:

   给出邮递员每天要走的路线,要你求出最小的消耗

分析:

   注意每一个字符串如three,表示邮递员起始于t,要走到e,而此时所消耗为字符串的长度,

   你要确定跑遍所有这些街道所需的最小旅程。旅程结束时必须回到起点的路口。注意到题目给出

   奇数度的顶点不超过两个,就是说有且只有两个,或者一个没有,所以根据欧拉回路可知,如果

   没有奇数顶点的话,直接输出所输入的总字符串长度即可。如果有两个奇数顶点的话,还要加上

   两个顶点之间的距离,就是说可能要求任意两顶点之间的距离,涉及到题目的输入规模最大不过为

   26,用floyd算法即可O(n^3)

 

#include <iostream>

#include <cstring>

#include <string>

#include <vector>

using namespace std;

#define X 27

#define INF 1000000000

string s;

int map[X][X],d[X];

int main()

{

   freopen("sum.in","r",stdin);

   freopen("sum.out","w",stdout);

   string end = "deadend";

   int x,y,ans;

   while(cin>>s)

   {

      vector<int> node;  //这是记录奇数顶点的数组

      for(int i=0;i<X;i++)  //初始化

      {

         for(int j=0;j<X;j++)

            map[i][j] = INF;   //两顶点之间没有回路即为距离无限远

         map[i][i] = 0;  //从该顶点出发回到该顶点

         d[i] = 0;   //统计各顶点度数

      }

      x = s[0]-'a';

      y = s[s.size()-1]-'a';

      map[x][y] = map[y][x] = s.size(); //flord算法的数组

      ans = s.size();

      d[x]++;

      d[y]++;

      while(cin>>s,s!=end)

      {

         x = s[0]-'a';

         y = s[s.size()-1]-'a';

         d[x]++;

         d[y]++;

         map[x][y] = map[y][x] = s.size();

         ans+=s.size();

      }

      for(int i=0;i<X;i++)

         if(d[i]%2)

            node.push_back(i);

      if(node.size()) //如果有奇数顶点的话

      {

         /////////////////floyd算法的实现

         for(int k=0;k<X;k++)

            for(int i=0;i<X;i++)

                for(int j=0;j<X;j++)

                   map[i][j] = min(map[i][j],map[i][k]+map[k][j]);

         cout<<ans+map[node[0]][node[1]]<<endl;  //加上两奇数顶点之间的距离

      }

      else

         cout<<ans<<endl;

   }

   return 0;

}

原文地址:https://www.cnblogs.com/yejinru/p/2398671.html