【题目大意】

给出邻接矩阵以及到达各个点需要付出的代价(起点和终点没有代价),求出从给定起点到终点的最短路,并输出字典序最小的方案。

【思路】

在堆优化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的更多相关文章

  1. 堆优化Dijkstra计算最短路+路径计数

    今天考试的时候遇到了一道题需要路径计数,然而蒟蒻从来没有做过,所以在考场上真的一脸懵逼.然后出题人NaVi_Awson说明天考试还会卡SPFA,吓得我赶紧又来学一波堆优化的Dijkstra(之前只会S ...

  2. HDU1385 Minimum Transport Cost (Floyd)

    Minimum Transport Cost Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/O ...

  3. hdu1385 Minimum Transport Cost 字典序最小的最短路径 Floyd

    求最短路的算法最有名的是Dijkstra.所以一般拿到题目第一反应就是使用Dijkstra算法.但是此题要求的好几对起点和终点的最短路径.所以用Floyd是最好的选择.因为其他三种最短路的算法都是单源 ...

  4. BZOJ 3040 最短路 (堆优化dijkstra)

    这题不是裸的最短路么?但是一看数据范围就傻了.点数10^6,边数10^7.这个spfa就别想了(本来spfa就是相当不靠谱的玩意),看来是要用堆优化dijkstra了.但是,平时写dijkstra时为 ...

  5. POJ 3635 - Full Tank? - [最短路变形][手写二叉堆优化Dijkstra][配对堆优化Dijkstra]

    题目链接:http://poj.org/problem?id=3635 题意题解等均参考:POJ 3635 - Full Tank? - [最短路变形][优先队列优化Dijkstra]. 一些口胡: ...

  6. PAT-1030 Travel Plan (30 分) 最短路最小边权 堆优化dijkstra+DFS

    PAT 1030 最短路最小边权 堆优化dijkstra+DFS 1030 Travel Plan (30 分) A traveler's map gives the distances betwee ...

  7. 【bzoj1097】[POI2007]旅游景点atr 状压dp+堆优化Dijkstra

    题目描述 FGD想从成都去上海旅游.在旅途中他希望经过一些城市并在那里欣赏风景,品尝风味小吃或者做其他的有趣的事情.经过这些城市的顺序不是完全随意的,比如说FGD不希望在刚吃过一顿大餐之后立刻去下一个 ...

  8. 【bzoj4016】[FJOI2014]最短路径树问题 堆优化Dijkstra+DFS树+树的点分治

    题目描述 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点分别走一次并返回. 往某一个点走时,选择总长度最短的路径走.若有多条长度最短的路径,则选择经过的顶点序列字典序最小的那条路径( ...

  9. UVA - 11374 - Airport Express(堆优化Dijkstra)

    Problem    UVA - 11374 - Airport Express Time Limit: 1000 mSec Problem Description In a small city c ...

随机推荐

  1. 【技巧总结】Penetration Test Engineer[5]-Operating System Security(SQL Server、MySQL提权)

    4.数据库安全基础 4.1.MSSQL 数据库角色权限 sysadmin:执行SQL Server中的任何动作 db_owner:可以执行数据库中技术所有动作的用户 public:数据库的每个合法用户 ...

  2. Callable和futrue、ExecutorService的用法

    首先说明是为了解决什么问题? 为了解决主线程无谓等待浪费服务器资源的问题.当主线程执行一个费时的操作时,比如客户端发起一个请求,该请求在服务器端处理很复杂,如需要调用其他系统的接口,总之比较耗时.这时 ...

  3. RobotFramework安装扩展库包Selenium2Library(三)

    Robot Framework扩展库包 http://robotframework.org/#libraries 一,自动化测试web端 1,pip安装SeleniumLibrary pip inst ...

  4. 项目中遇到的问题:Gradle传递性依赖冲突

    问题描述: 在调用别人接口时,由于他们接口做了拦截处理在使用RestTemplate调用时必须要使用@Qualifier("他们封装好的类"),需要导入jar包 gradle方式导 ...

  5. ggplot2使用初探

    ggplot2已经成为了R语言中数据可视化的同义词, 这是一个强大的工具, 可以帮助我们制作优良的图表, 创造出令人吃惊的图片, 下面我们一起学习(本博文参考了知乎问题如何使用 ggplot2中黄宝臣 ...

  6. 添加自签发的 SSL 证书为受信任的根证书

    原文:http://cnzhx.net/blog/self-signed-certificate-as-trusted-root-ca-in-windows/ 添加自签发的 SSL 证书为受信任的根证 ...

  7. 客户端使用less方法

    <link rel="stylesheet/less" type="text/css" href="/css/style.less"& ...

  8. 基于docker 搭建Prometheus+Grafana

    一.介绍Prometheus Prometheus(普罗米修斯)是一套开源的监控&报警&时间序列数据库的组合,起始是由SoundCloud公司开发的.随着发展,越来越多公司和组织接受采 ...

  9. Linux学习笔记:ps -ef、ps aux、kill -9

    一.查看进程命令 1.ps命令 Linux中的ps命令是Process Status的缩写. ps命令用来列出系统中当前运行的那些进程. ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻 ...

  10. Celery 框架学习笔记(生产者消费者模式)

    生产者消费者模式 在实际的软件开发过程中,经常会碰到如下场景:某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类.函数.线程.进程等).产生数据的模块,就形象地称为生产 ...