题目简介
求出有 n (1 < n ≤ 100) 个结点有向图中,结点 1 到结点 n 的最短路径,以及最短路径的条数。
第一行有 2 个整数 n,m (0 < m < 3000),接下来 m 行每行有三个整数 u,v,w 结点 u 到 v 有一条权为 w 的边 (w < 1e5)。
说明
Dijkstra模板题+重边判定。cnt数组记录最短路条数,same数组记录原来边的条数(也就记录了重边条数)。
#include <bits/stdc++.h>
using namespace std;
const int N = 105;
const int INF = 0x3f3f3f3f;
int v[N], d[N], mp[N][N], cnt[N], same[N][N];
int n, m;
void init()
{
memset(same, 0, sizeof(same));
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
mp[i][j] = INF;
int u, v, w;
while (m--) {
scanf("%d%d%d", &u, &v, &w);
mp[u-1][v-1] = w;
++same[u-1][v-1];
}
for (int i = 0; i < n; ++i) {
d[i] = (i ? INF : 0);
cnt[i] = (i ? 0 : 1);
}
}
void dijkstra()
{
for (int i = 0; i < n; ++i) {
int x, now = INF;
for (int y = 0; y < n; ++y)
if (!v[y] && d[y] <= now)
now = d[x=y];
v[x] = 1;
for (int y = 0; y < n; ++y)
if (!v[y]) {
if (d[x] + mp[x][y] == d[y])
cnt[y] += cnt[x] * same[x][y];
else if (d[x] + mp[x][y] < d[y]) {
cnt[y] = cnt[x] * same[x][y];
d[y] = d[x] + mp[x][y];
}
}
}
}
int main()
{
cin >> n >> m;
init();
memset(v, 0, sizeof(v));
dijkstra();
if (d[n-1] == INF) d[n-1] = -1;
cout << d[n-1] << " " << cnt[n-1] << endl;
return 0;
}