hdu Minimum Transport Cost(按字典序输出路径)

2024-08-28 10:38

本文主要是介绍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(按字典序输出路径)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1114527

相关文章

C++中实现调试日志输出

《C++中实现调试日志输出》在C++编程中,调试日志对于定位问题和优化代码至关重要,本文将介绍几种常用的调试日志输出方法,并教你如何在日志中添加时间戳,希望对大家有所帮助... 目录1. 使用 #ifdef _DEBUG 宏2. 加入时间戳:精确到毫秒3.Windows 和 MFC 中的调试日志方法MFC

Python使用Colorama库美化终端输出的操作示例

《Python使用Colorama库美化终端输出的操作示例》在开发命令行工具或调试程序时,我们可能会希望通过颜色来区分重要信息,比如警告、错误、提示等,而Colorama是一个简单易用的Python库... 目录python Colorama 库详解:终端输出美化的神器1. Colorama 是什么?2.

python 字典d[k]中key不存在的解决方案

《python字典d[k]中key不存在的解决方案》本文主要介绍了在Python中处理字典键不存在时获取默认值的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录defaultdict:处理找不到的键的一个选择特殊方法__missing__有时候为了方便起见,

python获取当前文件和目录路径的方法详解

《python获取当前文件和目录路径的方法详解》:本文主要介绍Python中获取当前文件路径和目录的方法,包括使用__file__关键字、os.path.abspath、os.path.realp... 目录1、获取当前文件路径2、获取当前文件所在目录3、os.path.abspath和os.path.re

hdu2544(单源最短路径)

模板题: //题意:求1到n的最短路径,模板题#include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#i

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

hdu 2093 考试排名(sscanf)

模拟题。 直接从教程里拉解析。 因为表格里的数据格式不统一。有时候有"()",有时候又没有。而它也不会给我们提示。 这种情况下,就只能它它们统一看作字符串来处理了。现在就请出我们的主角sscanf()! sscanf 语法: #include int sscanf( const char *buffer, const char *format, ... ); 函数sscanf()和

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :