HDU 1688 Sightseeing 【输出最短路+次短路条数】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1688
题目大意:给n个点,m条有向边。再给出起点s, 终点t。求出s到t的最短路条数+次短路条数。
思路:
1.最短路和次短路是紧密相连的,在最短路松弛操作中,当我们找到一条更短的路径,也就意味着之前的路径不再是最短路,而成为了次短路,利用这个关系可以实现状态的转移。
2.好久没写优先队列了,都忘记了加个 priority_queue, 这样才能写重载,才能排序。
注释在代码里:
#include<stdio.h>
#include<string.h>
#include<queue>
#define mem(a, b) memset(a, b, sizeof(a))
const int inf = 0x3f3f3f3f;
using namespace std; int n, m;
int tot, head[];
int dis[][], cnt[][];//dis数组记录最短路 0 和次短路 1 距离,cnt数组记录最短路 0 和次短路 1 条数
int vis[][]; struct Edge
{
int to, next;
int w;
}edge[]; void add(int a, int b, int w)
{
edge[++ tot].to = b;
edge[tot].w = w;
edge[tot].next = head[a];
head[a] = tot;
} struct Node//优先队列优化结构体,id为点的序号, dis为源点到该点的距离 p区分属于最短路还是次短路
{
int id, dis, p;
bool operator < (const Node &a)const
{
return dis > a.dis;
}
}no; void init()
{
mem(head, -), tot = ;
mem(vis, ); //代表源点到该点的距离未被确定
} void dij(int s, int t)
{
priority_queue<Node> Q;
while(!Q.empty())
Q.pop();
for(int i = ; i <= n; i ++) //初始化
{
dis[][i] = dis[][i] = inf;
cnt[][i] = cnt[][i] = ;
}
dis[][s] = ;
cnt[][s] = ;//源点到自己的最短路条数为1
no.p = , no.dis = , no.id = s;
Q.push(no);
while(!Q.empty())
{
Node a = Q.top();
Q.pop();
if(vis[a.p][a.id])
continue; //该p状态下已经确定过就跳过
vis[a.p][a.id] = ;
for(int i = head[a.id]; i != -; i = edge[i].next)
{
int to = edge[i].to;
if(dis[][to] > dis[a.p][a.id] + edge[i].w) //最短路可以更新(在0或1状态下找到一条更短的路)
{
dis[][to] = dis[][to]; //原来的最短路成为次短路
dis[][to] = dis[a.p][a.id] + edge[i].w;
cnt[][to] = cnt[][to];//次短路条数继承为原来的最短路条数
cnt[][to] = cnt[a.p][a.id];
no.p = , no.dis = dis[][to], no.id = to;
Q.push(no);
no.p = , no.dis = dis[][to], no.id = to;
Q.push(no);
}
else if(dis[][to] == dis[a.p][a.id] + edge[i].w)//最短路长度一样 更新最短路条数即可
{
cnt[][to] += cnt[a.p][a.id];
}
else if(dis[][to] > dis[a.p][a.id] + edge[i].w)//找到一条长度大于最短路但小于当前次短路的路径
{//将这条路变成次短路
dis[][to] = dis[a.p][a.id] + edge[i].w;
cnt[][to] = cnt[a.p][a.id];
no.p = , no.dis = dis[][to], no.id = to;
Q.push(no);
}
else if(dis[][to] == dis[a.p][a.id] + edge[i].w)
{
cnt[][to] += cnt[a.p][a.id];
}
}
}
} int main()
{
int T;
scanf("%d", &T);
while(T --)
{
init();
scanf("%d%d", &n, &m);
for(int i = ; i <= m; i ++)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
add(a, b, c);
}
int s, t;
scanf("%d%d", &s, &t);
dij(s, t);
int ans = cnt[][t]; //ans代表最短路的条数
if(dis[][t] + == dis[][t])
ans += cnt[][t];
printf("%d\n", ans);
}
return ;
}
HDU 1688 Sightseeing 【输出最短路+次短路条数】的更多相关文章
- HDU 1688 Sightseeing&HDU 3191 How Many Paths Are There(Dijkstra变形求次短路条数)
Sightseeing Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- 【最短路】HDU 1688 Sightseeing
题目大意 给出一个有向图(可能存在重边),求从\(S\)到\(F\)最短路的条数,如果次短路的长度仅比最短路的长度多1,那么再加上次短路的条数. 输入格式 第一行是数据组数\(T\). 对于魅族数据, ...
- HDU 1688 Sightseeing
题目链接:Sightseeing 题意:求最短路和比最短路长度+1的所有路径条数. 附代码:用数组记录最短和次短路径的长度和条数,一次更新,直到没有边可以更新. #include <stdio. ...
- HDU 3191 次短路长度和条数
http://www.cnblogs.com/wally/archive/2013/04/16/3024490.html http://blog.csdn.net/me4546/article/det ...
- hdu 1688 Sightseeing (最短路径)
Sightseeing Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- poj 3463/hdu 1688 求次短路和最短路个数
http://poj.org/problem?id=3463 http://acm.hdu.edu.cn/showproblem.php?pid=1688 求出最短路的条数比最短路大1的次短路的条数和 ...
- 2015多校第6场 HDU 5361 并查集,最短路
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5361 题意:有n个点1-n, 每个点到相邻点的距离是1,然后每个点可以通过花费c[i]的钱从i点走到距 ...
- HDU 3416 Marriage Match IV (求最短路的条数,最大流)
Marriage Match IV 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/Q Description Do not si ...
- POJ---3463 Sightseeing 记录最短路和次短路的条数
Sightseeing Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9247 Accepted: 3242 Descr ...
随机推荐
- Luogu P4109 [HEOI2015]定价 贪心
思路:找规律?$or$贪心. 提交:1次 题解: 发现:若可以构成$X0000$,答案绝对不会再在数字最后把$0$改成其他数: 若可以构成$XX50...0$更优. 所以左端点增加的步长是增加的($i ...
- PHP mysqli_get_host_info() 函数
定义和用法 mysqli_get_host_info() 函数返回 MySQL 服务器主机名和连接类型. 语法 mysqli_get_host_info(connection); 返回 MySQL 服 ...
- 图的最小生成树(java实现)
1.图的最小生成树(贪心算法) 我两个算法的输出都是数组表示的,当前的索引值和当前索引对应的数据就是通路,比如parent[2] = 5;即2和5之间有一个通路,第二个可能比较好理解,第一个有点混乱 ...
- 小米oj 反向位整数(简单位运算)
反向位整数 序号:#30难度:一般时间限制:1000ms内存限制:10M 描述 输入32位无符号整数,输出它的反向位. 例,输入4626149(以二进制表示为00000000010001101001 ...
- java中Switch的实现原理浅谈
switch的转换和具体系统实现有关,如果分支比较少,可能会转换为跳转指令(条件跳转指令和无条件跳转指令).但如果分支比较多,使用条件跳转会进行很多次的比较运算,效率比较低,可能会使用一种更为高效的方 ...
- 转:获取时间点前后一定间隔的时间 __timeShift()
接口获取时间点前后一定间隔的时间函数: __timeShift(时间格式, 特定时间点(缺省当前时间),时间间隔,地区格式(默认),变量名( 可不填,填写后其他地方用${变量名}引用 )) 举例: 1 ...
- Python图形用户界面-Tkinter
Tkinter是什么 python 特定的GUI界面,是一个图像的窗口,tkinter是python 自带的,可以编辑的GUI界面,我们可以用GUI 实现很多一个直观的功能,如何想开发一个计算器,如果 ...
- Java基础_通过模拟售票情景解决线程不安全问题
用代码来模拟铁路售票系统,实现通过四个售票点发售某日某次列车的100张车票,一个售票点用一个线程表示 第一种方法:通过继承Thread类的方法创建线程 package com.Gary1; publi ...
- BigDecimal常用的加减乘除算法、比较大小、不展示多余的零、保存两位小数点
项目中涉及到了BigDecimal的加.减.乘.比较大小.精确度的问题.所以在此总结一下,方便以后复习. //加法 BigDecimal coins = new BigDecimal("0& ...
- Beta冲刺(2/5)
队名:new game 组长博客 作业博客 组员情况 鲍子涵(队长) 过去两天完成了哪些任务 验收游戏素材 学习Unity 2D Animation系统 基本做完了人物的各个动画 接下来的计划 冲击E ...