Title
Portal AcWing 349 Dark Castle
answer
Count the number of shortest path spanning trees in the graph. Consider the process of spanning tree, take node 1 11 is the root, keep adding the node with the shortest shortest path among the nodes that have not joined the spanning treeiii , this time suretyiiThe predecessor nodes of the shortest path of i must all be in the spanning tree.
Use D ijkstra DijkstraD I J K S T R & lt A Solution single source shortest, statistics of the number of nodes in the shortest predecessor nodes, i.e. multiplied the answer in accordance with the principle of multiplication. The picture is a dense graph, using the plainD ijkstra DijkstraD i j k s t r a , total time complexityO (N 2) O(N^2)O ( N2)。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1005;
const ll mod = (1LL << 31) - 1;
int N, M, G[maxn][maxn], ds[maxn], cnt[maxn];
bool vs[maxn];
void Dijkstra(int s)
{
memset(ds, 0x3f, sizeof(ds));
memset(vs, 0, sizeof(vs));
ds[s] = 0;
for (int i = 1; i < N; ++i)
{
int x = 0;
for (int j = 1; j <= N; ++j)
if (!vs[j] && (!x || ds[j] < ds[x]))
x = j;
vs[x] = 1;
for (int j = 1; j <= N; ++j)
ds[j] = min(ds[j], ds[x] + G[x][j]);
}
}
int main()
{
scanf("%d%d", &N, &M);
memset(G, 0x3f, sizeof(G));
for (int i = 1; i <= N; ++i)
G[i][i] = 0;
for (int i = 1, x, y, z; i <= M; ++i)
scanf("%d%d%d", &x, &y, &z), G[x][y] = G[y][x] = min(G[x][y], z);
Dijkstra(1);
ll res = 1;
for (int i = 1; i <= N; ++i)
for (int j = 1; j <= N; ++j)
if (i != j && ds[i] + G[i][j] == ds[j])
++cnt[j];
for (int i = 2; i <= N; ++i)
res = (res * cnt[i]) % mod;
printf("%lld\n", res);
return 0;
}