HDU - 1385 Minimum Transport Cost(最短路+最小字典序路径)
2015-07-31 23:29
411 查看
题目大意:有N个村庄。过村庄时需要交一定的费用。现在问从村庄A,要运一批货物到村庄B,怎样走才能使费用达到最小,起始和终点都不用缴费
解题思路:这题借鉴了别人的思路,用字符串存储路径。
其实不用字符串也是可以处理的
解题思路:这题借鉴了别人的思路,用字符串存储路径。
其实不用字符串也是可以处理的
[code]#include <cstdio> #include <cstring> #include <queue> using namespace std; #define N 105 #define INF 0x3f3f3f3f struct Node { char str ; int dis; int len; }node ; int dis , tax , d , start, End, n; bool vis ; void init() { int x, y; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { scanf("%d", &x); dis[i][j] = x; if (x == -1 || i == j) dis[i][j] = INF; } } for (int i = 1; i <= n; i++) scanf("%d", &tax[i]); } void SPFA() { memset(vis, 0, sizeof(vis)); for (int i = 1; i <= n; i++) { d[i] = INF; node[i].len = 0; } node[start].str[0] = start; node[start].len = 1; d[start] = 0; vis[start] = true; queue<int> q; q.push(start); while (!q.empty()) { int t = q.front(); q.pop(); vis[t] = 0; for (int i = 1; i <= n; i++) { if (i != t) { //还没有走到终点,且最短距离变更 int tt = d[t] + dis[t][i]; if (i != End) tt += tax[i]; bool mark = false; if (tt <= d[i]) { //如果最短距离小于上一次的最短距离,直接更新 if (tt < d[i]) { d[i] = tt; mark = true; } else { //最短距离相等的,查看字典序是否最小 int len = min(node[i].len, node[t].len); //flag == 1表示上一个的字典序比较小,flag == 2表示当前的字典需比较小,flag == 0表示在长度相同的情况下,字典序相同 int flag = 0; for (int j = 0; j < len; j++) { if (node[i].str[j] < node[t].str[j]) { flag = 1; break; } if (node[i].str[j] > node[t].str[j]) { flag = 2; break; } } //当前的字典序比上一个小 if (flag == 2) { mark = true; } else if(flag == 0) { //如果在长度相同的情况下字典序还相同,那么上一个字典序,那么只可能是上一个的长度比当前的长 if (node[i].len > node[t].len) { if (node[i].str[node[t].len] > i) mark = true; } } } } if (mark) { for (int j = 0; j < node[t].len; j++) node[i].str[j] = node[t].str[j]; node[i].str[node[t].len] = i; node[i].len = node[t].len + 1; if (!vis[i]) { vis[i] = 1; q.push(i); } } } } } node[End].str[node[End].len] = '\0'; printf("From %d to %d :\n", start, End); printf("Path: %d", start); for (int i = 1; i < node[End].len; i++) printf("-->%d", node[End].str[i]); printf("\n"); printf("Total cost : %d\n\n", d[End]); } void solve() { while (1) { scanf("%d%d", &start, &End); if (start == -1 && End == -1) break; SPFA(); } } int main() { while (scanf("%d", &n) != EOF && n) { init(); solve(); } return 0; }
相关文章推荐
- GitHub SlidingMenu 搜到的两篇博客
- C#结构体的特点浅析
- Scala中使用Future进行并发处理
- Android开发记录20-获取缓存大小和清除缓存功能
- (九十九)桥接的介绍
- Java--接口
- (九十九)桥接的介绍
- Eclipse OSGi调试过程
- 博客之思
- shell脚本:查找文本 与 简单的grep
- 【leetcode c++】 112 Path Sum
- Ubuntu 12.04 配置记录
- HDU 2896 病毒侵袭 (AC自动机)
- Linux中profile、bashrc、bash_profile之间的区别和联系
- 14个Xcode中常用的快捷键操作
- JavaScript (常用的选择器和查询元素以及各种实例)
- Web项目导入的时候,各种配置文件报错解决办法
- Android学习笔记之Intent
- STM8L101F3P6低功耗
- JavaScript--DOM增删改操作