【题目大意】

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

【思路】

在堆优化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. [转]编译防火墙——C++的Pimpl惯用法解析

    impl(pointer to implementation, 指向实现的指针)是一种常用的,用来对“类的接口与实现”进行解耦的方法.这个技巧可以避免在头文件中暴露私有细节(见下图1),因此是促进AP ...

  2. [转]STL 容器一些底层机制

    1.vector 容器 vector 的数据安排以及操作方式,与 array 非常相似.两者的唯一区别在于空间的运用的灵活性.array 是静态空间,一旦配置了就不能改变,vector 是动态数组.在 ...

  3. Nagios Openstack Plugin

    Some simple example for checking Openstack services check nova service list #!/bin/sh export OS_PROJ ...

  4. day06作业

    一.方法 1.方法是完成特定功能的代码块. 修饰符  返回值类型  方法类型(参数类型  参数名1,参数类型  参数名2,...){ 方法体语句: return返回值: } 修饰符:目前就用publi ...

  5. python包/模块路径

    当Python执行import语句时,它会在一些路径中搜索Python模块和扩展模块.可以通过sys.path查看这些路径,比如: >>> import sys >>&g ...

  6. gcc/g++ 命令

    gcc & g++现在是gnu中最主要和最流行的c & c++编译器 .g++是c++的命令,以.cpp为主,对于c语言后缀名一般为.c.这时候命令换做gcc即可.其实是无关紧要的.其 ...

  7. es6之yield

    yield 关键字用来暂停和继续一个生成器函数.我们可以在需要的时候控制函数的运行. yield 关键字使生成器函数暂停执行,并返回跟在它后面的表达式的当前值.与return类似,但是可以使用next ...

  8. 一张图来帮你理解 SOA

    SOA 曾经一度是技术领域中最难以理解的一个概念.SOA 似乎让很多人感到困惑 - 一般来讲这是由于人们认为它拥有几乎神奇的力量.事实上 SOA 只是一个很简单的概念:SOA 由诸如 C++ 和 Ja ...

  9. 使用mybatis-generator-core自动生成代码

    SSM框架可以使用mybatis-generator-core-1.3.2.jar来自动生成代码,以下是配置和使用的代码. generatorConfig.xml <?xml version=& ...

  10. WordPress前台后台出现一片空白的原因以及解决办法

    WordPress前台后台出现空白的可能原因有以下: 这个问题,一般是在进行以下操作后出现的: 1.网站更换新主题2.网站安装或升级插件3.升级了Wordpress版本 其实问题的根源在于你的主题.插 ...