题目链接
【分析】
- 就是Floyd的最短路计数
- 用 d ( u , v ) d(u,v) d(u,v)表示从 u u u到 v v v的最短路长度, w ( u , v ) w(u,v) w(u,v)表示最短路的数量
- 分两种情况讨论
- 若 d i s ( i , j ) > d i s ( i , k ) + d i s ( k , j ) dis(i,j)>dis(i,k)+dis(k,j) dis(i,j)>dis(i,k)+dis(k,j),则令 w ( i , j ) = w ( i , k ) × w ( k , j ) w(i,j)=w(i,k) \times w(k,j) w(i,j)=w(i,k)×w(k,j),同时更新最短路长度
- 若 d i s ( i , j ) = d i s ( i , k ) + d i s ( k , j ) dis(i,j)=dis(i,k)+dis(k,j) dis(i,j)=dis(i,k)+dis(k,j),则令 w ( i , j ) + = w ( i , k ) × w ( k , j ) w(i,j)+=w(i,k) \times w(k,j) w(i,j)+=w(i,k)×w(k,j)
- 然后根据题目中的公式,算出每个结点的重要程度
【代码】
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 110;
int n, m;
ll w[maxn][maxn];
int d[maxn][maxn];
double ans[maxn];
int main()
{
scanf("%d%d", &n, &m);
memset(d, 0x3f, sizeof d);
for(int i = 1; i <= m; i++)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
d[a][b] = d[b][a] = c;
w[a][b] = w[b][a] = 1;
}
for(int k = 1; k <= n; k++)
{
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{
if(i == j || j == k || i == k)
continue;
if(d[i][j] == d[i][k] + d[k][j])
w[i][j] += w[i][k] * w[k][j];
if(d[i][j] > d[i][k] + d[k][j])
{
d[i][j] = d[i][k] + d[k][j];
w[i][j] = w[i][k] * w[k][j];
}
}
}
for(int k = 1; k <= n; k++)
{
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{
if(i == j || j == k || i == k)
continue;
if(d[i][j] == d[i][k] + d[k][j])
ans[k] += (double) (w[i][k] * w[k][j]) / w[i][j];
}
}
for(int i = 1; i <= n; i++)
printf("%.3lf\n", ans[i]);
return 0;
}