【题目链接】
【算法】
首先,跑floyd,计算最短路和最短路径数
然后,计算答案,枚举k,s,t,若dist[s][k] + dist[k][t] = dist[s][t],
那么,点对(s,t)对答案k的”贡献“就是c[s][k]*c[k][t]/c[s][t]
【代码】
#include<bits/stdc++.h> using namespace std; #define MAXN 110 const int INF = 1e9; int i,j,n,m,u,v,w; double ans[MAXN]; long long g[MAXN][MAXN],c[MAXN][MAXN]; inline void floyd() { int i,j,k; for (k = 1; k <= n; k++) { for (i = 1; i <= n; i++) { if (i == k) continue; for (j = 1; j <= n; j++) { if (i == j || k == j) continue; if (g[i][k] + g[k][j] < g[i][j]) { g[i][j] = g[i][k] + g[k][j]; c[i][j] = c[i][k] * c[k][j]; } else if (g[i][k] + g[k][j] == g[i][j]) c[i][j] += c[i][k] * c[k][j]; } } } } inline void calc() { int k,s,t; for (k = 1; k <= n; k++) { for (s = 1; s <= n; s++) { for (t = 1; t <= n; t++) { if (s == t) continue; if (g[s][k] + g[k][t] == g[s][t]) { if (c[s][t]) ans[k] += 1.0 * c[s][k] * c[k][t] / c[s][t]; } } } } } int main() { scanf("%d%d",&n,&m); for (i = 1; i <= n; i++) { for (j = 1; j <= n; j++) { g[i][j] = INF; } } while (m--) { scanf("%d%d%d",&u,&v,&w); g[u][v] = g[v][u] = w; c[u][v] = c[v][u] = 1; } floyd(); calc(); for (i = 1; i <= n; i++) printf("%.3lf ",ans[i]); return 0; }