【堆优化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 ...
随机推荐
- 浅析XSS与XSSI异同
浅析XSS与XSSI异同 这篇文章主要介绍了XSS与XSSI异同,跨站脚本(XSS)和跨站脚本包含(XSSI)之间的区别是什么?防御方法有什么不同?感兴趣的小伙伴们可以参考一下 Michael Cob ...
- Python——脚本(calculator)
<Python基础教程>(第二版) P123 书中原代码如下: class Calculator: def calculator(self,expression): self.value ...
- 2016.5.14——leetcode-HappyNumber,House Robber
leetcode:HappyNumber,House Robber 1.Happy Number 这个题中收获2点: 1.拿到题以后考虑特殊情况,代码中考虑1和4,或者说<6的情况,动手算下.( ...
- jquery easyui 扩展验证
$.extend($.fn.validatebox.defaults.rules, { idcard : {// 验证身份证 validator : function(value) ...
- imperva-指定url禁止访问
指定url禁止访问 应用到那个网站 访问一下查看告警
- 源码安装postgresql数据库
一般情况下,postgresql由非root用户启动. 1.创建postgres用户 groupadd postgres useradd -g postgres postgres 下面的操作都在pos ...
- 【Android开发日记】之入门篇(七)——Android数据存储(上)
在讲解Android的数据源组件——ContentProvider之前我觉得很有必要先弄清楚Android的数据结构. 数据和程序是应用构成的两个核心要素,数据存储永远是应用开发中最重要的主题之一,也 ...
- IOS使用xcode编译代码
一.安装xcode 在app store中搜索xcode然后点击安装即可. 二.创建第一个app 1.启动xcode,单击Lauchpad 2.单击xcode启动 3.单击“Create a new ...
- java 二叉树遍历
package com.lever; import java.util.LinkedList;import java.util.Queue; /** * 二叉树遍历 * @author lckxxy ...
- Linux学习笔记:cp和scp复制文件
拷贝文件和文件夹,在Linux上通过cp命令来实现. cp:用户当前机器的文件复制 scp:通过ssh本机和其他机器的文件复制 secure copy cp a.txt b.txt scp a.txt ...