题意:求两点之间最短路的数目加上比最短路长度大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 (次短路)的更多相关文章

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

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

  2. POJ - 3463 Sightseeing 最短路计数+次短路计数

    F - Sightseeing 传送门: POJ - 3463 分析 一句话题意:给你一个有向图,可能有重边,让你求从s到t最短路的条数,如果次短路的长度比最短路的长度多1,那么在加上次短路的条数. ...

  3. poj 3463 Sightseeing——次短路计数

    题目:http://poj.org/problem?id=3463 当然要给一个点记最短路和次短路的长度和方案. 但往优先队列里放的结构体和vis竟然也要区分0/1,就像把一个点拆成两个点了一样. 不 ...

  4. poj 3463 Sightseeing(次短路+条数统计)

    /* 对dij的再一次理解 每个点依旧永久标记 只不过这里多搞一维 0 1 表示最短路还是次短路 然后更新次数相当于原来的两倍 更新的时候搞一下就好了 */ #include<iostream& ...

  5. POJ 3463 Sightseeing (次短路经数)

    Sightseeing Time Limit: 2000MS   Memory Limit: 65536K Total Submissions:10005   Accepted: 3523 Descr ...

  6. POJ 3463 Sightseeing 【最短路与次短路】

    题目 Tour operator Your Personal Holiday organises guided bus trips across the Benelux. Every day the ...

  7. POJ 3463 Sightseeing 题解

    题目 Tour operator Your Personal Holiday organises guided bus trips across the Benelux. Every day the ...

  8. POJ 3463 Sightseeing

    最短路+次短路(Dijkstra+priority_queue) 题意是要求你找出最短路的条数+与最短路仅仅差1的次短路的条数. 開始仅仅会算最短路的条数,和次短路的长度.真是给次短路条数跪了.ORZ ...

  9. POJ 1637 Sightseeing tour(最大流)

    POJ 1637 Sightseeing tour 题目链接 题意:给一些有向边一些无向边,问能否把无向边定向之后确定一个欧拉回路 思路:这题的模型很的巧妙,转一个http://blog.csdn.n ...

随机推荐

  1. 12 jsp page 指令

    jsp 指令影响由 jsp 页面生成的 servlet 整体结构. jsp page 用来设置整个页面属性, 例如 import 就是引用这些类, 还可以设置 session 等等. <%@ p ...

  2. deep learning+ Depth Estimation

    Depth estimation/stereo matching/optical flow @CVPR 2017 Unsupervised Learning of Depth and Ego-Moti ...

  3. Stanford CoreNLP 3.6.0 中文指代消解模块调用失败的解决方案

    当前中文指代消解领域比较活跃的研究者是Chen和Vincent Ng,这两个人近两年在AAAI2014, 2015发了一些相关的文章,研究领域跨越零指代.代词指代.名词指代等,方法也不是很复杂,集中于 ...

  4. win7 激活相关

    命令 slui 1 slui 2 slui 3 slui 4 slmgr.vbs 需打开的服务 需要开启software protection和 SPP Notification service这两个 ...

  5. (转)负载均衡,回话保持,cookie

    servlet操作cookie:http://elf8848.iteye.com/blog/253198 负载均衡,回话保持:http://www.cnblogs.com/qq78292959/arc ...

  6. linux系统web项目运行环境搭建

    允许本地访问端口:iptables -P OUTPUT ACCEPT MySQL数据库安装1.yum install mysql 2.yum install mysql-server 3.删除MySQ ...

  7. Tweened Animations 渐变动作

    Tweened Animations 渐变动作 Animations分两类: 第一类:渐变的(Tweened): 淡入淡出(Alpha),旋转(Rotate),移动(Translate),缩放(Sca ...

  8. Flash Builder 相关

    1.Flex SDK 4.1 兼容性 Flex SDK 4.1 兼容 Flash Builder 4.0 ,因此在 Flash Builder 4.0 中使用 4.1 SDK 时可以使用设计视图 Fl ...

  9. c itoa和atoi

    #include <iostream> using namespace std; int main() { #if 1 ; ];//不要写成char*,因为没有分配空间 itoa(num, ...

  10. python序列中添加高斯噪声

    def wgn(x, snr): snr = 10**(snr/10.0) xpower = np.sum(x**2)/len(x) npower = xpower / snr return np.r ...