UVa Problem 117 - The Postal Worker Rings Once

// UVa Problem 117 - The Postal Worker Rings Once
// Verdict: Accepted
// Submission Date: 2011-12-21
// UVa Run Time: 0.040s
//
// 版权所有(C)2011,邱秋。metaphysis # yeah dot net
//
// [解题方法]
// 图论,欧拉路径。
// 根据题意,度为奇数的节点数为 1 的情况不可能出现,度为奇数的节点数目只可能为 0 或者 2。当度为
// 奇数的节点数为 0 时,很好办,走遍所有边仅一次的最小花费是所有边权的和,而当度为奇数的数目为 2
// 时,最小花费是所有边权的和加上这两个度数为奇数的节点之间的最短路径长度。
// 为了简便,可以采用 floyd_warshall 算法来得到两点间的最短路径长度。

#include <iostream>

using namespace std;

#define MAXV 27
#define INT_MAX (1 << 10)

// 邻接矩阵。
struct graph
{
	int weight[MAXV][MAXV];
	int nvertices;
};

// 利用 Floyd-Warshall 算法计算所有点对之间的最短距离。
void floyd_warshall(graph * g)
{
	int vertices = g->nvertices;

	for (int i = 1; i <= vertices; i++)
		g->weight[i][i] = 0;

	for (int k = 1; k <= vertices; k++)
		for (int i = 1; i <= vertices; i++)
			for (int j = 1; j <= vertices; j++)
				g->weight[i][j] =
					min(g->weight[i][j],
					g->weight[i][k] + g->weight[k][j]);
}

int main(int argc, char const *argv[])
{
	graph g;
	int length;
	string street;
	int crossroad[MAXV];

	length = 0;
	g.nvertices = MAXV - 1;
	for (int i = 1; i < MAXV; i++)
	{
		crossroad[i] = 0;
		for (int j = 1; j < MAXV; j++)
			g.weight[i][j] = INT_MAX;
	}

	while (cin >> street)
	{
		if (street == "deadend")
		{
			int start, end;
			bool found = false;
			for (int i = 1; i < MAXV; i++)
				if (crossroad[i] & 1)
				{
					if (found == false)
						start = i;
					else
						end = i;
					found = true;
				}

			if (found)
			{
				floyd_warshall(&g);
				cout << (length + g.weight[start][end]) << endl;
			}
			else
				cout << length << endl;

			length = 0;
			g.nvertices = MAXV - 1;
			for (int i = 1; i < MAXV; i++)
			{
				crossroad[i] = 0;
				for (int j = 1; j < MAXV; j++)
					g.weight[i][j] = INT_MAX;
			}
		}
		else
		{
			length += street.length();
			g.weight[street[0] - 'a' + 1][street[street.length() -
					1] - 'a' + 1] = street.length();
			g.weight[street[street.length() - 1] - 'a' +
				1][street[0] - 'a' + 1] = street.length();
			crossroad[street[0] - 'a' + 1]++;
			crossroad[street[street.length() - 1] - 'a' + 1]++;
		}
	}

	return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值