题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1688

题意:第k短路,这里要求的是第1短路(即最短路),第2短路(即次短路),以及路径条数,最后如果最短路和次短路长度差1,则输出两种路径条数之和,否则只输出最短路条数。

思路:dijkstra变形,注意状态的转移,代码上附了注释,就不多说了..

代码:

 #include <bits/stdc++.h>
#define MAXN 1010
using namespace std; vector<pair<int, int> > mp[MAXN]; //***记录图
int dist[MAXN][]; //***记录源点此时到 i 的距离状态即最短路距离和次短路距离
int cnt[MAXN][]; //***记录该点作为最短路节点和次短路节点入队次数
int vis[MAXN][]; //***标记该点的状态即在最短路中,在次短路中,或者未被标记
const int inf=0x3f3f3f3f; struct node{ //***重载比较符使优先队列非升序排列
int point, value, tag;//***point记录点, value记录源点到此点的距离,tag标记次点是在最短路中或者在次短路中
friend bool operator< (node a, node b){
return a.value!=b.value? a.value>b.value : a.point>b.point;
}
}; int dijkstra_heap_k(int s){
priority_queue<node> q;
memset(dist, 0x3f, sizeof(dist));
memset(vis, false, sizeof(vis));
memset(cnt, , sizeof(cnt)); dist[s][]=;
cnt[s][]=;
q.push({s, , }); while(!q.empty()){
node u=q.top();
int point=u.point;
int tag=u.tag;
q.pop();
if(vis[point][tag]){
continue;
}else{
vis[point][tag]=;
}
for(int i=; i<mp[point].size(); i++){
int v=mp[point][i].first;
int cost=mp[point][i].second; //***找到比当前最短路更优的路径
if(!vis[v][]&&dist[v][]>u.value+cost){
// 将之前的最短路变为次短路
if(dist[v][]!=inf){
dist[v][]=dist[v][];
cnt[v][]=cnt[v][];
q.push({v, dist[v][], });
}
//***更新最短路
dist[v][]=u.value+cost;
cnt[v][]=cnt[point][tag];
q.push({v, dist[v][], });
}else if(!vis[v][]&&dist[v][]==u.value+cost){
//***找到一条和当前最短路距离一样的路径,更新最短路数目
cnt[v][]+=cnt[point][tag];
}else if(!vis[v][]&&dist[v][]>u.value+cost){
// 比最短路长,比当前次短路短
dist[v][]=u.value+cost;
cnt[v][]=cnt[point][tag];
q.push({v, dist[v][], });
}else if(!vis[v][]&&dist[v][]==u.value+cost){
// 和当前次短路一样长
cnt[v][]+=cnt[point][tag];
}
}
}
} int main(void){
ios::sync_with_stdio(false), cin.tie(), cout.tie();
int t, n, m;
cin >> t;
while(t--){
cin >> n >> m;
while(m--){
int x, y, z;
cin >> x >> y >> z;
mp[x].push_back({y, z}); //**记录有向图
}
int s, e;
cin >> s >> e;
dijkstra_heap_k(s);
if(dist[e][]+==dist[e][]){
cout << cnt[e][]+cnt[e][] << endl;
}else{
cout << cnt[e][] << endl;
}
for(int i=; i<MAXN; i++){
mp[i].clear();
}
}
return ;
}

hdu1688(dijkstra求最短路和次短路)的更多相关文章

  1. Codeforces 938 D. Buy a Ticket (dijkstra 求多元最短路)

    题目链接:Buy a Ticket 题意: 给出n个点m条边,每个点每条边都有各自的权值,对于每个点i,求一个任意j,使得2×d[i][j] + a[j]最小. 题解: 这题其实就是要我们求任意两点的 ...

  2. 关于dijkstra求最短路(模板)

    嗯....   dijkstra是求最短路的一种算法(废话,思维含量较低,   并且时间复杂度较为稳定,为O(n^2),   但是注意:!!!!         不能处理边权为负的情况(但SPFA可以 ...

  3. Aizu-2249 Road Construction(dijkstra求最短路)

    Aizu - 2249 题意:国王本来有一个铺路计划,后来发现太贵了,决定删除计划中的某些边,但是有2个原则,1:所有的城市必须能达到. 2:城市与首都(1号城市)之间的最小距离不能变大. 并且在这2 ...

  4. ACM - 最短路 - AcWing 849 Dijkstra求最短路 I

    AcWing 849 Dijkstra求最短路 I 题解 以此题为例介绍一下图论中的最短路算法.先让我们考虑以下问题: 给定一个 \(n\) 个点 \(m\) 条边的有向图(无向图),图中可能存在重边 ...

  5. [ACM_图论] Domino Effect (POJ1135 Dijkstra算法 SSSP 单源最短路算法 中等 模板)

    Description Did you know that you can use domino bones for other things besides playing Dominoes? Ta ...

  6. 最短路和次短路问题,dijkstra算法

    /*  *题目大意:  *在一个有向图中,求从s到t两个点之间的最短路和比最短路长1的次短路的条数之和;  *  *算法思想:  *用A*求第K短路,目测会超时,直接在dijkstra算法上求次短路; ...

  7. BZOJ.2125.最短路(仙人掌 最短路Dijkstra)

    题目链接 多次询问求仙人掌上两点间的最短路径. 如果是在树上,那么求LCA就可以了. 先做着,看看能不能把它弄成树. 把仙人掌看作一个图(实际上就是),求一遍根节点到每个点的最短路dis[i]. 对于 ...

  8. poj 3463 最短路与次短路&&统计个数

    题意:求最短路和比最短路长度多1的次短路的个数 本来想图(有)方(模)便(版)用spfa的,结果妹纸要我看看dijkstra怎么解.... 写了三遍orz Ver1.0:堆优化+邻接表,WA //不能 ...

  9. poj 3463 Sightseeing( 最短路与次短路)

    http://poj.org/problem?id=3463 Sightseeing Time Limit: 2000MS   Memory Limit: 65536K Total Submissio ...

随机推荐

  1. Nginx Cache中$request_filename(转)

    对于Nginx的$request_filename变量指的就是请求的资源路径.在原先 OpenCDN节点端配置里面是这样的. location ~ .*\.(png|html|htm|ico|jpg| ...

  2. ubuntu安装opencv(自己编译)

    如果只需要python的,只需pip install opencv-python,然后apt-get一下下面第一点的东东. 1/ sudo apt-get install build-essentia ...

  3. join中级篇---------hash join & merge join & nested loop Join

    嵌套循环连接(Nested Loop Join) 循环嵌套连接是最基本的连接,正如其名所示那样,需要进行循环嵌套,嵌套循环是三种方式中唯一支持不等式连接的方式,这种连接方式的过程可以简单的用下图展示: ...

  4. history显示历史操作记录,并显示操作时间

    在查看历史的操作记录有两种方式1.在用户的目录下的.bash_history文件中[root@node1 ~]# vi ~/.bash_history rebootvi /etc/sysconfig/ ...

  5. 6410开发板sd卡启动时烧写u-boot.bin以及u-boot-spl-16k.bin步骤

    参考文档:<SMDK6410_IROM_APPLICATION NOTE_REV 1.00>(可以从这里下载到> 参考博客:Tekkaman的博文<u-boot-2010.09 ...

  6. NET LOCALGROUP命令详解(将用户添加到管理员组等)

    NET LOCALGROUP [groupname [/COMMENT:"text"]] [/DOMAIN] groupname {/ADD [/COMMENT:"tex ...

  7. 关于RabbitMQ简介

    RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现.AMQP 的出现其实也是应了广大人民群众的需求,虽然在同步消息通讯的世界里有很多公开标准 ...

  8. 如何用命令行删除EasyBCD开机选择项?

    用硬盘安装Ubuntu方法的windows双系统电脑上面,很多人都是用EasyBCD设置的开机启动选择.所以当我们不需要双系统的时候,或者已经删除双系统后,或者安装双系统失败的情况下,发现电脑的开机启 ...

  9. Download rtsp.c

    1. [代码][C/C++]代码 /* * Copyright (c) 2011, Jim Hollinger * All rights reserved. * * Redistribution an ...

  10. Android窗口系统第三篇---WindowManagerService中窗口的组织方式

    Android窗口系统第一篇—Window的类型与Z-Order确定 Android窗口系统第二篇—Window的添加过程 上面文章梳理了一个窗口的添加过程,系统中有很多应用,每个应用有多个Activ ...