【堆优化Dijkstra+字典序最短路方案】HDU1385-Minimum Transport Cost
【题目大意】
给出邻接矩阵以及到达各个点需要付出的代价(起点和终点没有代价),求出从给定起点到终点的最短路,并输出字典序最小的方案。
【思路】
在堆优化Dijkstra中,用pre记录前驱。如果新方案和旧方案相等,比较两个方案的字典序。
【坑点】
我先求出了最短路(包括终点要付出代价),输出的时候再减去终点的代价。
有可能会给出S==T的情况……在这种情况下,最短路就是0,减去代价要变成负数了QAQ所以要特判一下。坑了好几个小时orz
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;
const int MAXN=+;
const int INF=0x7fffffff; struct edge
{
int to,len;
}; vector<edge> E[MAXN];
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > pque;
int vis[MAXN],dis[MAXN],pre[MAXN],tax[MAXN];
int s1[MAXN],s2[MAXN],n; void addedge(int u,int v,int w)
{
E[u].push_back((edge){v,w});
} void init()
{
for (int i=;i<MAXN;i++) vector<edge>().swap(E[i]);
while (!pque.empty()) pque.pop();
for (int i=;i<=n;i++)
for (int j=;j<=n;j++)
{
int aij;
scanf("%d",&aij);
if (aij>= && i!=j) addedge(i,j,aij);
}
for (int i=;i<=n;i++) scanf("%d",&tax[i]);
} int compare(int now,int before)
{
memset(s1,,sizeof(s1));
memset(s2,,sizeof(s2));
int i=,j=-;
s1[]=before;
while (now!=) s1[++i]=now,now=pre[now];
while (before!=) s2[++j]=before,before=pre[before];
for (;i>= && j>=;i--,j--)
if (s1[i]<s2[j]) return ;
else if (s1[i]>s2[j]) return ;
return (s1<s2);
} int dijkstra(int S,int T)
{
for (int i=;i<=n;i++) vis[i]=,dis[i]=INF,pre[i]=-;
dis[S]=,pre[S]=;
pque.push(pair<int,int>(,S));
while (!pque.empty())
{
int u=pque.top().second;pque.pop();
vis[u]=;
for (int i=;i<E[u].size();i++)
{
int v=E[u][i].to,len=E[u][i].len+tax[v];
if (dis[v]>=dis[u]+len)
{
if (dis[v]>dis[u]+len)
{
dis[v]=dis[u]+len;
pre[v]=u;
pque.push(pair<int,int>(dis[v],v));
}
else if (dis[v]==dis[u]+len && compare(u,v))
{
pre[v]=u;
pque.push(pair<int,int>(dis[v],v));
}
}
}
} int i=,now=T;
while (now!=) s1[++i]=now,now=pre[now];
printf("From %d to %d :\n",S,T);
printf("Path: ");
while (i>=)
{
printf("%d",s1[i--]);
if (i!=) printf("-->");
}
printf("\nTotal cost : %d\n\n",(S==T)?:dis[T]-tax[T]);
//注意如果S==T的时候,就不要减去tax了,否则会出现负值。
} void solve()
{
int a,b;
while (scanf("%d%d",&a,&b))
{
if (a==- && a==b) return;
dijkstra(a,b);
}
} int main()
{
while (scanf("%d",&n))
{
if (n==) break;
init();
solve();
}
return ;
}
附上随机数据生成:
#include<bits/stdc++.h>
using namespace std; int main()
{
freopen("samplein.txt", "w", stdout);
srand((unsigned)time(NULL));
int n=rand() % ;
int ne;
cout<<n<<endl;
for (int i=;i<n;i++)
{
for (int j=;j<n;j++)
{
if (i==j)
{
printf("%d",);
}
else
{
if((rand()%n)<(n/))
{
printf("-1");
}
else
{
printf("%d",(rand()%(n-)+));
}
}
printf(" ");
}
printf("\n"); } for (int i=;i<n;i++)
{
printf("%d ",(rand()%n));
} printf("\n");
int tmp=rand()%n;
for (int i=;i<tmp;i++)
{
int temp1=(rand()%(n-)+);
int temp2=(rand()%(n-)+);
printf("%d %d\n",temp1,temp2); } printf("%d %d\n",-,-);
printf("%d\n",); fclose(stdout);
return ;
}
【堆优化Dijkstra+字典序最短路方案】HDU1385-Minimum Transport Cost的更多相关文章
- 堆优化Dijkstra计算最短路+路径计数
今天考试的时候遇到了一道题需要路径计数,然而蒟蒻从来没有做过,所以在考场上真的一脸懵逼.然后出题人NaVi_Awson说明天考试还会卡SPFA,吓得我赶紧又来学一波堆优化的Dijkstra(之前只会S ...
- HDU1385 Minimum Transport Cost (Floyd)
Minimum Transport Cost Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/O ...
- hdu1385 Minimum Transport Cost 字典序最小的最短路径 Floyd
求最短路的算法最有名的是Dijkstra.所以一般拿到题目第一反应就是使用Dijkstra算法.但是此题要求的好几对起点和终点的最短路径.所以用Floyd是最好的选择.因为其他三种最短路的算法都是单源 ...
- BZOJ 3040 最短路 (堆优化dijkstra)
这题不是裸的最短路么?但是一看数据范围就傻了.点数10^6,边数10^7.这个spfa就别想了(本来spfa就是相当不靠谱的玩意),看来是要用堆优化dijkstra了.但是,平时写dijkstra时为 ...
- POJ 3635 - Full Tank? - [最短路变形][手写二叉堆优化Dijkstra][配对堆优化Dijkstra]
题目链接:http://poj.org/problem?id=3635 题意题解等均参考:POJ 3635 - Full Tank? - [最短路变形][优先队列优化Dijkstra]. 一些口胡: ...
- PAT-1030 Travel Plan (30 分) 最短路最小边权 堆优化dijkstra+DFS
PAT 1030 最短路最小边权 堆优化dijkstra+DFS 1030 Travel Plan (30 分) A traveler's map gives the distances betwee ...
- 【bzoj1097】[POI2007]旅游景点atr 状压dp+堆优化Dijkstra
题目描述 FGD想从成都去上海旅游.在旅途中他希望经过一些城市并在那里欣赏风景,品尝风味小吃或者做其他的有趣的事情.经过这些城市的顺序不是完全随意的,比如说FGD不希望在刚吃过一顿大餐之后立刻去下一个 ...
- 【bzoj4016】[FJOI2014]最短路径树问题 堆优化Dijkstra+DFS树+树的点分治
题目描述 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点分别走一次并返回. 往某一个点走时,选择总长度最短的路径走.若有多条长度最短的路径,则选择经过的顶点序列字典序最小的那条路径( ...
- UVA - 11374 - Airport Express(堆优化Dijkstra)
Problem UVA - 11374 - Airport Express Time Limit: 1000 mSec Problem Description In a small city c ...
随机推荐
- IE的双边距Bug以及解决办法
display:inline和display:block区别 一.什么是双边距Bug? 先来看图: 我们要让绿色盒模型在蓝色盒模型之内向左浮动,并且距蓝色盒模型左侧100像素.这个例子很常见,比如在网 ...
- linux环境下mysql默认是区分表名大小写的
在linux环境下,mysql默认表明是区分大小写的,我们可以查看全局变量发现: mysql> show variables like 'lower%'; +------------------ ...
- 使用mysql的SUBSTRING_INDEX函数解决项目中编码非重复问题的实现方案!
一 SUBSTRING_INDEX函数介绍 作用:按关键字截取字符串 substring_index(str,delim,count) 说明:substring_index(被截取字段,关键字,关键字 ...
- 【bzoj题解】1012 最大数
题目描述 现在请求你维护一个数列,要求提供以下两种操作:1.查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2.插入操作.语法:A ...
- 采用dlopen、dlsym、dlclose加载动态链接库【总结】【转】
转自:https://www.cnblogs.com/Anker/p/3746802.html 1.前言 为了使程序方便扩展,具备通用性,可以采用插件形式.采用异步事件驱动模型,保证主程序逻辑不变,将 ...
- Access中替代case when的方法 .
最近在做一个用Access的东东,其中用到了case when的方式,但是Access是不支持这种语法的,查询知道IIf和Swith可以作为替代,总结如下: IIf(expr, truepart, f ...
- Android 抽屉导航
原文地址 http://developer.android.com/training/implementing-navigation/nav-drawer.html 创建抽屉导航 导航抽屉是在 屏幕左 ...
- HTML5 localStorage、sessionStorage 作用域
一.localStorage localStorage有效期:永不失效,除非web应用主动删除. localStorage作用域:localStorage的作用域是限定在文档源级别的.文档源通过协议. ...
- 深度解析eclipse控制台
第一个按钮:scroll lock 控制台在打印sql语句的时候会一直滚动,用这个按钮可以固定住控制台不乱跑; 第二个按钮:show console when standard out changes ...
- Executor
一.为什么需要Executor?为了更好的控制多线程,JDK提供了一套线程框架Executor,帮助开发人员有效的进行线程控制.他们都在java.util.concurrent包中,是JDK并发包的核 ...