hdu Minimum Transport Cost(按字典序输出路径)
http://acm.hdu.edu.cn/showproblem.php?
pid=1385
求最短路。要求输出字典序最小的路径。
spfa:拿一个pre[]记录前驱,不同的是在松弛的时候。要考虑和当前点的dis值相等的情况,解决的办法是dfs找出两条路径中字典序较小的。pre[]去更新。
把路径当做字符串处理。
我仅仅用之前的pre去更新当前点,并没考虑到起点到当前点的整个路径,事实上这样并不能保证是字典序最小。wa了N次。于是乎搜了下题解,发现用spfa解的非常少。看到了某大牛的解法如上,感觉非常赞的想法。
#include <stdio.h>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#define LL long long
#define _LL __int64
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 110; int n;
int tax[maxn];
int Map[maxn][maxn];
int dis[maxn],inque[maxn];
int pre[maxn];
int pos = 0; void dfs(int u, char *s)
{
if(u == -1)
return;
dfs(pre[u],s);
s[pos++] = u+'0';
} bool solve(int v, int u)
{
char s1[maxn],s2[maxn]; //寻找先前的路径
pos = 0;
dfs(v,s1);
s1[pos] = '\0';
//寻找由u更新的路径
pos = 0;
dfs(u,s2);
s2[pos++] = v+'0';
s2[pos] = '\0'; if(strcmp(s1,s2) > 0) return true;
return false; } int spfa(int s, int t)
{
queue <int> que;
memset(dis,INF,sizeof(dis));
memset(inque,0,sizeof(inque));
memset(pre,-1,sizeof(pre)); dis[s] = 0;
inque[s] = 1;
que.push(s); while(!que.empty())
{
int u = que.front();
que.pop();
inque[u] = 0; for(int v = 1; v <= n; v++)
{
if(Map[u][v] > 0)
{
int tmp = dis[u] + Map[u][v] + tax[v]; if(tmp < dis[v])//直接更新
{
dis[v] = tmp;
pre[v] = u;
if(!inque[v])
{
inque[v] = 1;
que.push(v);
}
}
else if(tmp == dis[v] && solve(v,u))
{
pre[v] = u;
} }
}
} return dis[t];
} void output(int s, int t)
{
int res[maxn];
int cnt = 0;
int tmp = t; while(pre[tmp] != -1)
{
res[cnt++] = tmp;
tmp = pre[tmp];
}
res[cnt] = s;
printf("Path: ");
for(int i = cnt; i >= 1; i--)
printf("%d-->",res[i]);
printf("%d\n",res[0]);
} int main()
{
while(~scanf("%d",&n) && n)
{
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
scanf("%d",&Map[i][j]);
}
for(int i = 1; i <= n; i++)
scanf("%d",&tax[i]);
int u,v;
while(~scanf("%d %d",&u,&v))
{
if(u == -1 && v == -1) break;
int tmp1 = tax[u];//备份
int tmp2 = tax[v]; tax[u] = 0;
tax[v] = 0; printf("From %d to %d :\n",u,v);
int ans = spfa(u,v);
output(u,v);
printf("Total cost : %d\n\n",ans);
//恢复备份
tax[u] = tmp1;
tax[v] = tmp2; }
}
return 0;
}
floyd:pre[i][j]记录i到j路径上距离i近期的点,输出路径时按pre正向输出。感觉floyd非常强大啊,还能够这样记录路径。
#include <stdio.h>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <math.h>
#include <string.h>
#include <stack>
#include <queue>
#define LL long long
#define _LL __int64
using namespace std; const int INF = 0x3f3f3f3f;
const int maxn = 110;
int Map[maxn][maxn];
int tax[maxn];
int pre[maxn][maxn];
int n; void floyd()
{
//初始化
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
pre[i][j] = j; for(int k = 1; k <= n; k++)
{
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
if(Map[i][k] > 0 && Map[k][j] > 0)
{
int tmp = Map[i][k] + Map[k][j] + tax[k]; if(tmp < Map[i][j]) //小于直接更新
{
Map[i][j] = tmp;
pre[i][j] = pre[i][k];
}
else if(tmp == Map[i][j])
{
pre[i][j] = min(pre[i][k],pre[i][j]);
}
}
}
}
}
} void output(int s, int t)
{
printf("Path: ");
int tmp = s;
while(tmp != t)
{
printf("%d-->",tmp);
tmp = pre[tmp][t];
}
printf("%d\n",t); } int main()
{
while(~scanf("%d",&n) && n)
{
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{
scanf("%d",&Map[i][j]);
if(Map[i][j] == -1)
Map[i][j] = INF;
} for(int i = 1; i <= n; i++)
scanf("%d",&tax[i]); int u,v;
floyd();
while(~scanf("%d %d",&u,&v))
{
if(u == -1 && v == -1) break;
printf("From %d to %d :\n",u,v);
output(u,v);
printf("Total cost : %d\n\n",Map[u][v]);
}
}
return 0;
}
hdu Minimum Transport Cost(按字典序输出路径)的更多相关文章
- HD1385Minimum Transport Cost(Floyd + 输出路径)
Minimum Transport Cost Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/O ...
- HDU 1385 Minimum Transport Cost( Floyd + 记录路径 )
链接:传送门 题意:有 n 个城市,从城市 i 到城市 j 需要话费 Aij ,当穿越城市 i 的时候还需要话费额外的 Bi ( 起点终点两个城市不算穿越 ),给出 n × n 大小的城市关系图,-1 ...
- ZOJ 1456 Minimum Transport Cost(floyd+后继路径记录)
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1456 题意:求最短路并且输出字典序最小的答案. 思路:如果用dijkstr ...
- hdu 1385 Minimum Transport Cost(floyd && 记录路径)
Minimum Transport Cost Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/O ...
- HDU 1385 Minimum Transport Cost (Dijstra 最短路)
Minimum Transport Cost http://acm.hdu.edu.cn/showproblem.php?pid=1385 Problem Description These are ...
- Minimum Transport Cost(floyd+二维数组记录路径)
Minimum Transport Cost Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/O ...
- hdu 1385 Minimum Transport Cost (Floyd)
Minimum Transport CostTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Ot ...
- HDU1385 Minimum Transport Cost (Floyd)
Minimum Transport Cost Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/O ...
- ZOJ 1456 Minimum Transport Cost(Floyd算法求解最短路径并输出最小字典序路径)
题目链接: https://vjudge.net/problem/ZOJ-1456 These are N cities in Spring country. Between each pair of ...
随机推荐
- date---显示或设置系统时间与日期
date命令可以用来显示或设定系统的日期与时间,格式设定为一个加号后接数个标记,其中可用的标记列表如下: 时间方面: %H : 小时(00..23) %M : 分钟(00..59) %p : 显示本地 ...
- 微信小程序从零开始开发步骤(一)搭建开发环境
从零到有写一个小程序系列专题,很早以前就想写来分享,但由于项目一直在进展,没有过多的时间研究技术,现在可以继续分享了. 1:注册 用没有注册过微信公众平台的邮箱注册一个微信公众号, 申请帐号 ,网址: ...
- thinkphp事务处理以及无效时的解决方案(整理)
thinkphp事务处理以及无效时的解决方案(整理) 一.总结 一句话总结:要程序里面支持事务,首先连接的数据库和数据表必须支持事务 mysql 1.InnoDB和MyISAM对事务的支持怎么样? I ...
- java三元表达式编程规范问题
package day01; public class Program { public static void main(String[] args) { // TODO Auto-g ...
- JS数组排序技巧汇总(冒泡、sort、快速、希尔等排序)
本文实例总结了JS数组排序技巧.分享给大家供大家参考,具体如下: 1.冒泡排序 var temp = 0; for (var i = 0; i < array.length; i++) { fo ...
- CISP/CISA 每日一题 七
CISA 每日一题(答) 确保只有恰当授权的出站交易才能被处理,控制目的: 1.出站交易是基于授权而被启动: 2.出站交易包含了唯一的预先授权的交易类型: 3.出站交易只能被发送到合法的商业伙伴那里. ...
- 洛谷 P3003 [USACO10DEC]苹果交货Apple Delivery
洛谷 P3003 [USACO10DEC]苹果交货Apple Delivery 题目描述 Bessie has two crisp red apples to deliver to two of he ...
- 【习题 7-8 UVA-12107】Digit Puzzle
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 迭代加深搜索. 枚举最大层数.(也即改变的数字个数 然后枚举第一个改哪个数字,第二个改哪个数字.. 一定要注意字典序问题. 每次优先 ...
- 【2017"百度之星"程序设计大赛 - 初赛(B)】度度熊的交易计划
[链接]点击打开链接 [题意] 在这里写题意 [题解] 先设一个超级源点,向每个片区都建一条边,容量为b,费用为-a; 然后从每个片区再连一条边,指向一个超级汇点. 容量为d,费用为c; 然后从起点到 ...
- SSO单点登录学习总结(1)——单点登录(SSO)原理解析
SSO的概念: 单点登录SSO(Single Sign-On)是身份管理中的一部分.SSO的一种较为通俗的定义是:SSO是指访问同一服务器不同应用中的受保护资源的同一用户,只需要登录一次,即通过一个应 ...