题目
思路
dijkstra比较好,通过BFS来不断寻找到n这条路径
需要用road列表(path) 记录前一个点以及 dist列表来记录第一个点到第i个点的距离
由于题目要求问多个最短路径,所以还得需要一个count数组来记录到这个路的最短路径到底有多少条
dijkstra就是先把数据都存放在邻接表上面
然后初始化dist列表,除了自己到自己以外,其他所有的路径初始为INF(无法到达)
然后把自己存入队列{0,1} 0代表距离,1代表去自己本身。
接着根据邻接表依次拿出1结点邻接的点,判断是否来过这个点?如果已经来过这个点了就不要在重复来了,没来过就进行判断。
判断是否经过这个mid点到end是否比之前到end点更快
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x3f3f3f
struct edge
{
int end,cost;
};
vector<edge> e[200];
int mark[200];
int road[200];
ll cou[200];
ll dist[200];
void print(int n)
{
if(n == 0) return;
print(road[n]);
cout << n << " ";
}
int main()
{
int n,m;
cin >> n >> m;
for(int i = 0; i < m; i++)
{
int start, end, cost;
cin >> start >> end >> cost;
e[start].push_back({end,cost});
e[end].push_back({start,cost});
//创造邻接表
}
priority_queue<pair<int, int>,
vector<pair<int, int>>,
greater<pair<int, int>>> que;
// queue<pair<int,int>> que;
for(int i = 2; i <= n; i++) dist[i] = INF;
//初始化点1到其他点的距离
dist[1] = 0;//到自己肯定是0
que.push({0,1});//1是距离,2是到哪个点
cou[1] = 1;//到自己肯定有一种方法
while(!que.empty())
{
int mid = que.top().second;//起始到mid
que.pop();
if(mark[mid]) continue;//来过了就别来了
mark[mid] = true;//记录来过
for(auto data : e[mid])
{//bfs来遍历
int end = data.end;//要去的终点
int cost = data.cost;//cost
if(!mark[end])//还没遍历到这个点
{
if(dist[end] > dist[mid] + cost)
{//用if只拿最小部分
dist[end] = dist[mid] + cost;
cou[end] = cou[mid];//更新路径数量
road[end] = mid;//更新路径的一种可能
que.push({dist[end], end});//BFS塞进去
}
else if(dist[end] == dist[mid] + cost)
{
cou[end] += cou[mid];//加路径
}
}
}
}
if(cou[n] == 0)
{
cout << -1 << endl;
cout << 0 << endl;
cout << -1 << endl;
}
else
{
cout << dist[n] << endl;
cout << cou[n] << endl;
print(n);
}
}