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;
}