题意:

给定一张有向图,求最短路的条数,如果次短路长度 = 最短路 + 1,则输出最短路和次短路条数的和。

思路:

1. 一开始想到 POJ 2449 求 k 短路的方法求解,case 都过的差不多了,无奈 TLE 了,于是找到题解,求最短路的过程中顺带求出次短路;

2. 分别设置二维数组 d[0][i] 表示 s 到 i 的最短路,d[1][i] 表示 s 到 i 的次短路,cnt[][] , vis[][] 数组都是类似的;

3. 依然有地方需要注意的是,当更新某一点最短路/次短路的时候,计数的数组要赋值为其父节点引向其的技术值,具体见代码;

// 方法 1 (dijkstra 47ms)#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;const int MAXN = 1010;
const int INFS = 0x3FFFFFFF;struct edge {int to, cost;edge(int _to, int _cost) : to(_to), cost(_cost) {}
};vector<edge> G[MAXN];
int d[2][MAXN], cnt[2][MAXN];
bool vis[2][MAXN];struct ST {int u, dd, r;ST(int _u, int _dd, int _r) : u(_u), dd(_dd), r(_r) {}bool operator < (const ST& o) const { return dd > o.dd; }
};int dijkstra(int s, int t, int n) {for (int i = 1; i <= n; i++) {d[0][i] = d[1][i] = INFS;cnt[0][i] = cnt[1][i] = 0;vis[0][i] = vis[1][i] = false;}priority_queue<ST> Q;Q.push(ST(s, 0, 0));d[0][s] = 0, cnt[0][s] = 1;while (!Q.empty()) {ST o = Q.top(); Q.pop();int u = o.u, r = o.r;if (vis[r][u]) continue;else vis[r][u] = true;for (int i = 0; i < G[u].size(); i++) {edge& e = G[u][i];int dis = o.dd + e.cost;if (dis < d[0][e.to]) {if (d[0][e.to] != INFS) {cnt[1][e.to] = cnt[0][e.to];d[1][e.to] = d[0][e.to];Q.push(ST(e.to, d[1][e.to], 1));}d[0][e.to] = dis;cnt[0][e.to] = cnt[r][u];Q.push(ST(e.to, dis, 0));}else if (dis == d[0][e.to]) {cnt[0][e.to] += cnt[r][u];} else if (dis < d[1][e.to]) {d[1][e.to] = dis;cnt[1][e.to] = cnt[r][u];Q.push(ST(e.to, dis, 1));} else if (dis == d[1][e.to]) {cnt[1][e.to] += cnt[r][u];}}}int ans = cnt[0][t];if (d[0][t] == d[1][t] - 1)ans += cnt[1][t];return ans;
}int main() {int cases;scanf("%d", &cases);while (cases--) {int n, m;scanf("%d%d", &n, &m);for (int i = 1; i <= n; i++)G[i].clear();for (int i = 0; i < m; i++) {int u, v, cost;scanf("%d%d%d", &u, &v, &cost);G[u].push_back(edge(v, cost));}int s, t;scanf("%d%d", &s, &t);printf("%d\n", dijkstra(s, t, n));}return 0;
}
// 方法 2:(K 短路解法 TLE)#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;const int MAXN = 1010;
const int INFS = 0x3FFFFFFF;struct edge {int to, cost;edge(int _to, int _cost) : to(_to), cost(_cost) {}
};struct ST {int u, cost, f;ST(int _u, int _cost, int _f): u(_u), cost(_cost), f(_f) {}bool operator < (const ST& other) const { return f > other.f; }
};vector<edge> G[MAXN], P[MAXN];
int d[MAXN];
bool vis[MAXN];void SPFA(int s, int n) {for (int i = 1; i <= n; i++)d[i] = INFS, vis[i] = false;queue<int> Q;Q.push(s); d[s] = 0, vis[s] = true;while (!Q.empty()) {int x = Q.front(); Q.pop();vis[x] = false;for (int i = 0; i < P[x].size(); i++) {edge& e = P[x][i];if (d[e.to] > d[x] + e.cost) {d[e.to] = d[x] + e.cost;if (!vis[e.to]) {vis[e.to] = true; Q.push(e.to);}}}}
}int solve(int s, int t, int n) {priority_queue<ST> Q;Q.push(ST(s, 0, d[t]));int count = 0;bool flag = false;while (!Q.empty()) {ST o = Q.top(); Q.pop();if (o.u == t) {if (o.cost == d[s])count += 1;else if (o.cost == d[s] + 1)count += 1;elsereturn count;}for (int i = 0; i < G[o.u].size(); i++) {edge& e = G[o.u][i];Q.push(ST(e.to, e.cost + o.cost, e.cost + o.cost + d[e.to]));}}return count;
}int main() {int cases;scanf("%d", &cases);while (cases--) {int n, m, s, t;scanf("%d%d", &n, &m);for (int i = 1; i <= n; i++)G[i].clear(), P[i].clear();for (int i = 0; i < m; i++) {int u, v, cost;scanf("%d%d%d", &u, &v, &cost);G[u].push_back(edge(v, cost));P[v].push_back(edge(u, cost));}scanf("%d%d", &s, &t);SPFA(t, n);printf("%d\n", solve(s, t, n));}return 0;
}

转载于:https://www.cnblogs.com/kedebug/archive/2013/04/27/3047958.html

POJ 3463 Sightseeing(次短路问题)相关推荐

  1. POJ 3463 Sightseeing dijkstra

    题目链接:http://poj.org/problem?id=3463 题意:给定一个图,找最短路和比最短路多1的路的条数. 思路1:将次短路也当作一种"最短"的状态,去扩展状态. ...

  2. POJ 1637 Sightseeing tour(最大流)

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

  3. poj 1637 Sightseeing tour 混合欧拉图判定

    POJ - 1637点我点我:-) Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000KB   64bit IO Format: %ll ...

  4. poj 1637 Sightseeing tour

    http://poj.org/problem?id=1637 题意: 给出一张混合图,判断是否存在欧拉回路 原理: 1.存在欧拉回路的充要条件:所有点入度=出度 2.给无向边随便定向不会影响点的|出度 ...

  5. POJ 3255 Roadblocks 次短路

    和Dijksta求最短路一样,只是要维护两个数组:最短路d1,次短路d2.然后更新的时候注意细节. //#pragma comment(linker, "/STACK:1024000000, ...

  6. POJ - 1734 Sightseeing trip(最小环+输出路径)

    题目链接:点击查看 题目大意:给定一张无向图,求图中至少一个包含三个点的环,环上的节点不重复,并且环上的边的长度之和最小.该问题称为无向图的最小环问题.在本题中,你需要输出最小环的方案,若最小环不唯一 ...

  7. POJ - 1847 Tram(最短路)

    题目链接:点击查看 题目大意:火车从起点开到终点,轨道上有很多岔路口,每个岔路口都有很多方向(火车能够选择任意一个方向行驶),但是默认 的是第一个方向,如果要选择其他的方向需要增加一次切换的操作,问最 ...

  8. POJ - 3255 Roadblocks(次短路)

    题目链接:点击查看 题目大意:求次短路 题目分析:唉,限时训练的时候遇到的这个题,明明之前系统学习过次短路和次小生成树这个方面的知识的,可能是很长时间没 用,板子都忘掉了,不过还好,在考试的时候想到了 ...

  9. ROADS POJ - 1724(最短路+邻接表+dfs)

    题意: N个城市,编号1到N.城市间有R条单向道路.有长度和过路费两个属性.Bob只有K块钱,他想从城市1走到城市N.问最短共需要走多长的路.如果到不了N,输出-1. 题目: N cities nam ...

最新文章

  1. OpenCV使用问题汇总
  2. linux 下查mac
  3. OpenCV中使用神经网络 CvANN_MLP
  4. (chap4 IP协议) 多播和子网掩码
  5. 公众号推荐:Python入门、统计学、推荐系统、机器学习、深度学习、数据分析...
  6. python的float精度_python 中的各种小数点后的精度处理方式
  7. 查看oracle的块大小,查看操作系统块大小
  8. 11. javacript高级程序设计-DOM扩展
  9. 阿里巴巴研究员刘国华:阿里巴巴智能运维体系建设
  10. wxml 判断 小程序_如何判断小程序外包公司是否靠谱
  11. 再说共识性算法Raft
  12. Java中private修饰变量的继承问题
  13. 深入浅出python学习
  14. python监听键盘事件pyhook用法_python 监听键盘事件pyHook
  15. AH快递单打印查询软件V3.68
  16. 【HDU 4609】3-idiots
  17. linux sin()编译
  18. 仿酒仙网的一款jQuery侧栏弹出导航栏特效
  19. Wordpress搭建笔录
  20. 统计学常识笔记整理(二)

热门文章

  1. [转]线程安全 c/c++
  2. Spark RDD-行动算子
  3. python之地基(三)
  4. (摘抄)HTTP 协议详解
  5. #ifdef __cplusplus extern C { #endif”的定义的含义
  6. Eclipse CDT中EOF输入的解决方法
  7. 最精准的view,canvas,surface之间的关系
  8. 第三周项目三-输出星号图(4)
  9. jquery对ajax的支持
  10. JDK和JRE的概念与区别