POJ 3463 Sightseeing (次短路)
题意:求两点之间最短路的数目加上比最短路长度大1的路径数目
分析:可以转化为求最短路和次短路的问题,如果次短路比最短路大1,那么结果就是最短路数目加上次短路数目,否则就不加。
求解次短路的过程也是基于Dijkstra的思想。算法中用一个二维数组d[u][tag](tag=0代表最短路,1代表次短路)来记录最短路和次短路的长度,cnt[u][tag]记录二者的数目。所以每个点都有两个访问状态,一个是最短路已经确定,另一个是次短路已经确定,所以vis[u][tag]数组也是二维的。
每次维护邻接点的状态时,有四种可能情况:
1.最短路长度需要更新。此时还需判断次短路是否需要更新,若最短路不存在,则不用更新;若最短路存在,则用最短路覆盖次短路。
2.最短路数目需要更新。传递过来的路径长度与当前最短路相等,那么数量要加上去。
3.次短路长度需要更新。
4.次短路数目需要更新。
且算法可以用优先队列改善效率。
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<queue>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
typedef int LL;
const int maxn =1e3+,maxm = 2e4+;
const LL INF =0x3f3f3f3f;
LL dis[maxn][]; //最短路和次短路长度
struct Edge{
int to,next;
LL val;
};
struct Node{
int u,tag;
bool operator <(const Node &rhs) const {return dis[u][tag]>dis[rhs.u][rhs.tag];}
}; struct SPFA{
int n,m,tot;
Edge edges[maxm];
int head[maxn];
bool vis[maxn][];
int cnt[maxn][]; //最短路和次短路条数 void init(int n){
this->n = n;
this->tot=;
memset(head,-,sizeof(head));
}
void Addedge(int u,int v ,LL dist){
edges[tot].to = v;
edges[tot].val = dist;
edges[tot].next = head[u];
head[u] = tot++;
}
void spfa(int s){
for(int i=;i<=n;++i){
dis[i][]=INF,cnt[i][]=;
dis[i][]=INF,cnt[i][]=;
vis[i][]=vis[i][]=false;
}
dis[s][]=,cnt[s][]=;
priority_queue<Node> Q;
Q.push((Node){s,});
while(!Q.empty()){
Node x =Q.top();Q.pop();
int u = x.u,tag = x.tag;
if(vis[u][tag]) continue;
vis[u][tag] = true;
for(int i=head[u];~i;i=edges[i].next){
int v =edges[i].to,w =edges[i].val;
int tmp = dis[u][tag] + w;
if(dis[v][]>tmp) { //需要更新最短路
if(dis[v][]!=INF){ //将次短路覆盖
dis[v][] = dis[v][];
cnt[v][] = cnt[v][];
Q.push((Node){v,});
}
dis[v][]=tmp;
cnt[v][]=cnt[u][tag];
Q.push((Node){v,});
}
else if(dis[v][]==tmp){ //最短路长度不变,数量增加
cnt[v][]+=cnt[u][tag];
}
else if(dis[v][]>tmp){ //次短路长度改变
dis[v][] = tmp;
cnt[v][] = cnt[u][tag];
Q.push((Node){v,});
}
else if(dis[v][]==tmp){ //次短路长度不变,数量增加
cnt[v][]+=cnt[u][tag];
}
}
}
}
}G; #define LOCAL
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int T,N,M,u,v, s,t;
LL tmp;
scanf("%d",&T);
while(T--){
scanf("%d%d",&N,&M);
G.init(N);
for(int i=;i<=M;++i){
scanf("%d%d%d",&u,&v,&tmp);
G.Addedge(u,v,tmp);
}
scanf("%d%d",&s,&t);
G.spfa(s);
if(dis[t][]==dis[t][]+)
G.cnt[t][]+=G.cnt[t][];
printf("%d\n",G.cnt[t][]);
}
return ;
}
POJ 3463 Sightseeing (次短路)的更多相关文章
- poj 3463 Sightseeing( 最短路与次短路)
http://poj.org/problem?id=3463 Sightseeing Time Limit: 2000MS Memory Limit: 65536K Total Submissio ...
- POJ - 3463 Sightseeing 最短路计数+次短路计数
F - Sightseeing 传送门: POJ - 3463 分析 一句话题意:给你一个有向图,可能有重边,让你求从s到t最短路的条数,如果次短路的长度比最短路的长度多1,那么在加上次短路的条数. ...
- poj 3463 Sightseeing——次短路计数
题目:http://poj.org/problem?id=3463 当然要给一个点记最短路和次短路的长度和方案. 但往优先队列里放的结构体和vis竟然也要区分0/1,就像把一个点拆成两个点了一样. 不 ...
- poj 3463 Sightseeing(次短路+条数统计)
/* 对dij的再一次理解 每个点依旧永久标记 只不过这里多搞一维 0 1 表示最短路还是次短路 然后更新次数相当于原来的两倍 更新的时候搞一下就好了 */ #include<iostream& ...
- POJ 3463 Sightseeing (次短路经数)
Sightseeing Time Limit: 2000MS Memory Limit: 65536K Total Submissions:10005 Accepted: 3523 Descr ...
- POJ 3463 Sightseeing 【最短路与次短路】
题目 Tour operator Your Personal Holiday organises guided bus trips across the Benelux. Every day the ...
- POJ 3463 Sightseeing 题解
题目 Tour operator Your Personal Holiday organises guided bus trips across the Benelux. Every day the ...
- POJ 3463 Sightseeing
最短路+次短路(Dijkstra+priority_queue) 题意是要求你找出最短路的条数+与最短路仅仅差1的次短路的条数. 開始仅仅会算最短路的条数,和次短路的长度.真是给次短路条数跪了.ORZ ...
- POJ 1637 Sightseeing tour(最大流)
POJ 1637 Sightseeing tour 题目链接 题意:给一些有向边一些无向边,问能否把无向边定向之后确定一个欧拉回路 思路:这题的模型很的巧妙,转一个http://blog.csdn.n ...
随机推荐
- SecureCRT超级终端使用说明
SecureCRT超级终端使用说明 一.连接POS机 1.运行SecureCRT,选择‘文件’菜单,在下拉菜单中选择‘快速连接’菜单: 2.在弹出的对话框中按如下图选择参数: 3.POS端开机,且数据 ...
- 2018 ACM ICPC 南京赛区 酱油记
Day 1: 早上6点起床打车去车站,似乎好久没有这么早起床过了,困到不行,在火车上睡啊睡就睡到了南京.南航离南京南站很近,地铁一站就到了,在学校里看到了体验坐直升机的活动,感觉很强.报道完之后去吃了 ...
- Java反射基础(二)
获取域 1. 通过反射API可以获取到类中公开的静态域和对象中的实例域.得到表示域的java.lang.reflect.Field类的对象之后,就可以获取和设置域的值. 与获取构造方法类似,Cla ...
- hdu 4294(bfs)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4294 思路:题目的意思是说,给你n,k,则求出n的正整数倍数,使得这个数字在k进制下表示的时候需要的不 ...
- 国内Android源码下载
因国内网络被墙的原因,按照Google提供下载Android源码的方式很难下载到,所以记录一下国内下载Android源码的步骤,主要利用的是清华大学的镜像下载. 说明: 下载环境:Ubuntu14.0 ...
- 【BZOJ4571】[Scoi2016]美味 主席树
[BZOJ4571][Scoi2016]美味 Description 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1≤i≤n).有 m 位顾客,第 i 位顾客的期望值 ...
- java如何遍历当月所有的日期?
转自:https://zhidao.baidu.com/question/360215274.html import java.util.ArrayList;import java.util.Cale ...
- Spring Data JPA 一:环境搭建
搭建开发环境是最麻烦的事情,各种冲突各种异常,记一下搭建过程,仅供大家参考: 用的gradle搭建的项目,先亮一下项目的大概目录: 注意一定要是这个 web工程用spring/src/main/web ...
- [LintCode] 二叉树的后序遍历
The recursive solution is trivial and I omit it here. Iterative Solution using Stack (O(n) time and ...
- Powershell Get-ChildItem 筛选文件,文件处理
使用Where-Object也可以根据其它属性来过滤. Dir | Where-Object { $_.CreationTime -gt [datetime]::Parse("May 12, ...