找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 382|回复: 2

大臣的旅费

[复制链接]

14

主题

65

回帖

0

积分

新手上路

积分
0
发表于 2013-6-24 23:42:52 | 显示全部楼层 |阅读模式
很久以前,T王国空前繁荣。为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市。

为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首都直接或者通过其他大城市间接到达。同时,如果不重复经过大城市,从首都到达每个大城市的方案都是唯一的。

J是T国重要大臣,他巡查于各大城市之间,体察民情。所以,从一个城市马不停蹄地到另一个城市成了J最常做的事情。他有一个钱袋,用于存放往来城市间的路费。

聪明的J发现,如果不在某个城市停下来修整,在连续行进过程中,他所花的路费与他已走过的距离有关,在走第x千米到第x+1千米这一千米中(x是整数),他花费的路费是x+10这么多。也就是说走1千米花费11,走2千米要花费23。

J大臣想知道:他从某一个城市出发,中间不休息,到达另一个城市,所有可能花费的路费中最多是多少呢?

输入格式:
输入的第一行包含一个整数n,表示包括首都在内的T王国的城市数
城市从1开始依次编号,1号城市为首都。
接下来n-1行,描述T国的高速路(T国的高速路一定是n-1条)
每行三个整数Pi, Qi, Di,表示城市Pi和城市Qi之间有一条高速路,长度为Di千米。

输出格式:
输出一个整数,表示大臣J最多花费的路费是多少。

样例输入:
5
1 2 2
1 3 1
2 4 5
2 5 4

样例输出:
135

样例说明:
大臣J从城市4到城市5要花费135的路费。

资源约定:
峰值内存消耗 < 64M
CPU消耗  < 5000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

提交时,注意选择所期望的编译器类型。

14

主题

65

回帖

0

积分

新手上路

积分
0
 楼主| 发表于 2013-6-30 00:09:44 | 显示全部楼层
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 调试开关
#define _DEBUG_ 0

// 最大顶点个数
#define MAX_VERTEX 32

// 取最大值
#define MAX(a, b) ((a) > (b) ? (a) : (b))

// 检测分配内存是否成功
#define CHECK_MALLOC(p)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; \
{&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; \
&#160;&#160;&#160;&#160;if (NULL == p)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;\
&#160;&#160;&#160;&#160;{&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; \
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;printf("malloc error.\n");&#160;&#160;&#160;&#160;\
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return -1;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;\
&#160;&#160;&#160;&#160;}&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; \
}

// 邻接点结构定义
typedef struct EdgeNode
{
&#160;&#160;&#160;&#160;int adjVex;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// 邻接点在顶点表中的下标
&#160;&#160;&#160;&#160;int weight;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// 权值,这里指距离
&#160;&#160;&#160;&#160;
&#160;&#160;&#160;&#160;struct EdgeNode *next;&#160;&#160; // 下一个邻接点
}EdgeNode;

// 顶点表结点定义
typedef struct
{
&#160;&#160;&#160;&#160;int index;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; // 城市编号
&#160;&#160;&#160;&#160;EdgeNode *firstEdge;&#160;&#160;&#160;&#160; // 第一个邻接点
}AdjList[MAX_VERTEX];

// 邻接表结构定义
typedef struct
{
&#160;&#160;&#160;&#160;int vertexNum;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// 顶点数
&#160;&#160;&#160;&#160;int edgeNum;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// 边数
&#160;&#160;&#160;&#160;AdjList adjList;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// 邻接表
}GraphAdjList;

// -------------------------------------------------------------------------
// - 函 数 名: initAdjList
// - 功能描述: 初始化邻接表
// - 输入参数: vertexNum:顶点个数;edgeNum:边数
// - 输出参数: graph:邻接图
// - 返 回 值: void
// - 备&#160;&#160;&#160;&#160;注:
// -------------------------------------------------------------------------
void initAdjList(GraphAdjList *graph, int vertexNum, int edgeNum)
{
&#160;&#160;&#160;&#160;int i;
&#160;&#160;&#160;&#160;
&#160;&#160;&#160;&#160;memset(graph, 0, sizeof(GraphAdjList));
&#160;&#160;&#160;&#160;
&#160;&#160;&#160;&#160;graph->vertexNum = vertexNum;
&#160;&#160;&#160;&#160;graph->edgeNum = edgeNum;
&#160;&#160;&#160;&#160;
&#160;&#160;&#160;&#160;for (i = 0; i < graph->vertexNum; i++)
&#160;&#160;&#160;&#160;{
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;graph->adjList.index = i;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;graph->adjList.firstEdge = NULL;
&#160;&#160;&#160;&#160;}
}

// -------------------------------------------------------------------------
// - 函 数 名: createAdjList
// - 功能描述: 创建邻接表
// - 输入参数: 无
// - 输出参数: graph:邻接图
// - 返 回 值: 0:成功;其他:失败
// - 备&#160;&#160;&#160;&#160;注:
// -------------------------------------------------------------------------
int createAdjList(GraphAdjList *graph)
{
&#160;&#160;&#160;&#160;int i;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// 循环变量
&#160;&#160;&#160;&#160;int from;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; // 起始城市编号
&#160;&#160;&#160;&#160;int to;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; // 目标城市编号
&#160;&#160;&#160;&#160;int distance;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; // 两城市间距离
&#160;&#160;&#160;&#160;EdgeNode *pEdgeNode = NULL;
&#160;&#160;&#160;&#160;
&#160;&#160;&#160;&#160;for (i = 0; i < graph->edgeNum; i++)
&#160;&#160;&#160;&#160;{
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// 从标准输入获取高速公路信息
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;fflush(stdin);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;scanf("%d %d %d", &from, &to, &distance);

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// 将高速公路信息加入邻接表
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;pEdgeNode = (EdgeNode*)malloc(sizeof(EdgeNode));
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;CHECK_MALLOC(pEdgeNode);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;pEdgeNode->adjVex = to - 1;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;pEdgeNode->weight = distance;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;pEdgeNode->next = graph->adjList[from-1].firstEdge;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;graph->adjList[from-1].firstEdge = pEdgeNode;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;pEdgeNode = (EdgeNode*)malloc(sizeof(EdgeNode));
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;CHECK_MALLOC(pEdgeNode);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;pEdgeNode->adjVex = from - 1;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;pEdgeNode->weight = distance;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;pEdgeNode->next = graph->adjList[to-1].firstEdge;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;graph->adjList[to-1].firstEdge = pEdgeNode;
&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;
&#160;&#160;&#160;&#160;return 0;
}

#if _DEBUG_
// -------------------------------------------------------------------------
// - 函 数 名: printGraphAdjList
// - 功能描述: 打印邻接表
// - 输入参数: graph:邻接表指针
// - 输出参数: 无
// - 返 回 值: void
// - 备&#160;&#160;&#160;&#160;注: 调试使用,格式为:"[城市编号]: ->(相邻城市编号,距离)"
// -------------------------------------------------------------------------
void printGraphAdjList(const GraphAdjList *graph)
{
&#160;&#160;&#160;&#160;int i;
&#160;&#160;&#160;&#160;EdgeNode *pEdgeNode = NULL;
&#160;&#160;&#160;&#160;
&#160;&#160;&#160;&#160;puts("=========================");
&#160;&#160;&#160;&#160;for (i = 0; i < graph->vertexNum; i++)
&#160;&#160;&#160;&#160;{
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;printf("[%d]: ", graph->adjList.index);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;pEdgeNode = graph->adjList.firstEdge;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;while (NULL != pEdgeNode)
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;printf("->(%d,%d)", pEdgeNode->adjVex + 1, pEdgeNode->weight + 1);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;pEdgeNode = pEdgeNode->next;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;printf("\n");
&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;puts("=========================");
}
#endif

// -------------------------------------------------------------------------
// - 函 数 名: dfs
// - 功能描述: 深度优先遍历邻接图
// - 输入参数: graph:邻接图指针;vertex1:起始城市编号;vertex2:目标城市编号
// - 输出参数: distance:两城市之间距离;visit:访问标记
// - 返 回 值: 0:成功;1:失败
// - 备&#160;&#160;&#160;&#160;注:
// -------------------------------------------------------------------------
int dfs(GraphAdjList *graph, int vertex1, int vertex2, int *distance, int visit[])
{
&#160;&#160;&#160;&#160;EdgeNode *pEdgeNode = NULL;

&#160;&#160;&#160;&#160;// 之前已经访问过,回退
&#160;&#160;&#160;&#160;if (0 != visit[vertex1])
&#160;&#160;&#160;&#160;{
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return 1;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;// 打访问标记
&#160;&#160;&#160;&#160;visit[vertex1] = 1;

&#160;&#160;&#160;&#160;// 找到目标城市,返回成功
&#160;&#160;&#160;&#160;if (graph->adjList[vertex1].index == vertex2)
&#160;&#160;&#160;&#160;{
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return 0;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;// 遍历当前城市的所有邻接城市
&#160;&#160;&#160;&#160;pEdgeNode = graph->adjList[vertex1].firstEdge;
&#160;&#160;&#160;&#160;while (NULL != pEdgeNode)
&#160;&#160;&#160;&#160;{
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// 没访问过则访问
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if (0 == visit[pEdgeNode->adjVex])
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// 加上与当前城市之间的距离
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;*distance += pEdgeNode->weight;

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// 递归访问城市
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if (0 == dfs(graph, pEdgeNode->adjVex, vertex2, distance, visit))
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return 0;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;pEdgeNode = pEdgeNode->next;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;// 在当前城市的所有邻接城市中均未找到目标城市,减去距离,回退
&#160;&#160;&#160;&#160;*distance -= graph->adjList[vertex1].firstEdge->weight;

&#160;&#160;&#160;&#160;return 1;
}

// -------------------------------------------------------------------------
// - 函 数 名: getDistance
// - 功能描述: 获取两城市之间的距离
// - 输入参数: graph:邻接图;vertex1:城市1下标;vertex2:城市2下标
// - 输出参数: 无
// - 返 回 值: int 两城市之间的距离
// - 备&#160;&#160;&#160;&#160;注:
// -------------------------------------------------------------------------
int getDistance(GraphAdjList *graph, int vertex1, int vertex2)
{
&#160;&#160;&#160;&#160;int distance = 0;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; // 城市距离
&#160;&#160;&#160;&#160;int visited[MAX_VERTEX] = {0};&#160;&#160;&#160;&#160;// 访问标记

&#160;&#160;&#160;&#160;(void)dfs(graph, vertex1, vertex2, &distance, visited);

&#160;&#160;&#160;&#160;return distance;
}

// -------------------------------------------------------------------------
// - 函 数 名: getMaxDistance
// - 功能描述: 获取图中最远的两座城市之间的距离
// - 输入参数: graph:邻接图
// - 输出参数: 无
// - 返 回 值: int 最大距离
// - 备&#160;&#160;&#160;&#160;注:
// -------------------------------------------------------------------------
int getMaxDistance(GraphAdjList *graph)
{
&#160;&#160;&#160;&#160;int maxDistance = 0;
&#160;&#160;&#160;&#160;int tmpDistance;
&#160;&#160;&#160;&#160;int i, j;

&#160;&#160;&#160;&#160;// 计算各对城市之间的距离,取最大值
&#160;&#160;&#160;&#160;for (i = 0; i < graph->vertexNum; i++)
&#160;&#160;&#160;&#160;{
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;for (j = i + 1; j < graph->vertexNum; j++)
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;tmpDistance = getDistance(graph, i, j);

#if _DEBUG_
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;printf("(%d,%d): %d\n", i + 1, j + 1, tmpDistance);
#endif

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;maxDistance = MAX(tmpDistance, maxDistance);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;return maxDistance;
}

// -------------------------------------------------------------------------
// - 函 数 名: calcFee
// - 功能描述: 根据距离计算路费
// - 输入参数: distance:距离
// - 输出参数: 无
// - 返 回 值: int:路费
// - 备&#160;&#160;&#160;&#160;注:
// -------------------------------------------------------------------------
int calcFee(int distance)
{
&#160;&#160;&#160;&#160;return (10 * distance + distance * (distance + 1) / 2);
}

int main()
{
&#160;&#160;&#160;&#160;int cityNum;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; // 城市数
&#160;&#160;&#160;&#160;int maxDistance = 0;&#160;&#160;&#160;&#160;&#160;&#160; // 城市间最大距离
&#160;&#160;&#160;&#160;GraphAdjList graph;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// 邻接图

&#160;&#160;&#160;&#160;scanf("%d", &cityNum);
&#160;&#160;&#160;&#160;
&#160;&#160;&#160;&#160;// 初始化邻接表
&#160;&#160;&#160;&#160;initAdjList(&graph, cityNum, cityNum - 1);
&#160;&#160;&#160;&#160;
&#160;&#160;&#160;&#160;// 建立边表
&#160;&#160;&#160;&#160;if (0 != createAdjList(&graph))
&#160;&#160;&#160;&#160;{
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;printf("create graph failed.\n");
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return -1;
&#160;&#160;&#160;&#160;}

#if _DEBUG_
&#160;&#160;&#160;&#160;// 打印邻接表
&#160;&#160;&#160;&#160;printGraphAdjList(&graph);
#endif

&#160;&#160;&#160;&#160;// 遍历邻接表寻找最远的两座城市
&#160;&#160;&#160;&#160;maxDistance = getMaxDistance(&graph);

&#160;&#160;&#160;&#160;// 计算并打印最多的路费
&#160;&#160;&#160;&#160;printf("%d\n", calcFee(maxDistance));
&#160;&#160;&#160;&#160;
&#160;&#160;&#160;&#160;return 0;
}

210

主题

371

回帖

0

积分

管理员

积分
0
发表于 2013-6-30 10:28:03 | 显示全部楼层

回 boyfaceone 的帖子

boyfaceone:#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 调试开关
....... (2013-06-30 00:09)
狂赞啊。。。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

果子博客
扫码关注微信公众号

Archiver|手机版|小黑屋|风叶林

GMT+8, 2026-2-1 16:39 , Processed in 0.123623 second(s), 20 queries .

Powered by 风叶林

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表