非常好的题目
“可能存在多条路径的情况下”
求解从指定源点到汇点的最短路和次短路
dijkstra框架结构基本不变,松弛的时候才用以下方式
/*
求s到t的最短路与次短路(这里要求只比最短路多1)的条数之和
联想到最小,次小的一种更新关系:
if(x<最小)更新最小,次小
else if(==最小)更新方法数
else if(x<次小)更新次小
else if(x==次小)更新方法数
同时记录s到u最短,次短路及方法数
用一个堆每次取最小的,更新完后再入堆
还是那个原理,第一次遇到的就是最优的,然后vi标记为真
方法数注意是加法原理,不是乘法
\
-- u -- v 所以是加法原理
/
*/
单纯的单源最短路径的话,只有第一种情况
#include <iostream>
#include <vector>
#include <map>
#include <list>
#include <set>
#include <deque>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <cstdio>
#include <iomanip>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <string>
#include <sstream>
#include <cstring>
#include <queue>
using namespace std;
///宏定义
const int INF = 1000000000;
const int MAXN = 10010;
///全局变量 和 函数
int cases;
int n, m; //顶点数,边数
struct edge
{
int to;
int len;
int next;
}e[MAXN];
int s, t;
struct node
{
int a; //当前结点编号
int kind; //当前处理结点类型,0表示最短路,1表示次短路
int w; //当前结点的最小值,类似于dist[a]
bool operator < (const node & b)const
{
return w > b.w;
}
}start, temp, tex;
priority_queue<node> Q;
int qq[1005]; //邻接表存储,本题可能存在多条路径
bool vis[1005][2];
int cn[1005][2],d[1005][2];//分别表示最短,次短路的数目 最短次短路的长度
int dijkstra()
{
/*
求s到t的最短路与次短路(这里要求只比最短路多1)的条数之和
联想到最小,次小的一种更新关系:
if(x<最小)更新最小,次小
else if(==最小)更新方法数
else if(x<次小)更新次小
else if(x==次小)更新方法数
同时记录s到u最短,次短路及方法数
用一个堆每次取最小的,更新完后再入堆
还是那个原理,第一次遇到的就是最优的,然后vi标记为真
方法数注意是加法原理,不是乘法
\
-- u -- v 所以是加法原理
/
*/
int i, j;
for (i = 0; i <= n; ++i)
{
d[i][0] = INF;
d[i][1] = INF;
cn[i][0] = 0;
cn[i][1] = 0;
vis[i][0] = false;
vis[i][1] = false;
}
while (!Q.empty())
Q.pop();
//初值
start.a = s;
start.w = 0;
start.kind = 0;
d[s][0] = 0;
cn[s][0] = 1;
Q.push(start);
while (!Q.empty())
{
temp = Q.top();
Q.pop();
if (vis[temp.a][temp.kind])
continue;
vis[temp.a][temp.kind] = true;
//松弛
for (i = qq[temp.a]; i != 0; i = e[i].next)
{
int tl, tj;
tl = temp.w + e[i].len; //从当前结点到下一个结点的数值
tj = e[i].to; //下一个结点
if (tl < d[tj][0])
{
if (d[tj][0] < d[tj][1])
{
d[tj][1] = d[tj][0];
cn[tj][1] = cn[tj][0];
tex.a = tj;
tex.w = d[tj][1];
tex.kind = 1;
Q.push(tex);
}
d[tj][0] = tl;
cn[tj][0] = cn[temp.a][0];
tex.a = tj;
tex.w = tl;
tex.kind = 0;
Q.push(tex);
}
else if (tl == d[tj][0])
{
cn[tj][0] += cn[temp.a][0];
}
else if (tl < d[tj][1])
{
d[tj][1] = tl;
cn[tj][1] = cn[temp.a][temp.kind];
tex.a = tj;
tex.w = tl;
tex.kind = 1;
Q.push(tex);
}
else if (tl == d[tj][1])
{
cn[tj][1] += cn[temp.a][temp.kind];
}
}
}
//输出结果
if(d[t][0] + 1 == d[t][1])
return cn[t][0] + cn[t][1];
return cn[t][0];
}
int main()
{
///变量定义
int i, j;
scanf("%d", &cases);
while (cases--)
{
scanf("%d%d", &n, &m);
memset(qq, 0, sizeof(qq));
for (i = 1; i <= m; ++i)
{
int from, to, len;
scanf("%d%d%d", &from, &to, &len);
e[i].to = to;
e[i].len = len;
e[i].next = qq[from];
qq[from] = i;
}
scanf("%d%d", &s, &t);
printf("%d\n", dijkstra());
}
///结束
return 0;
}