首先,利用floyd得到:a[i][j]表示i->j的最短路,c[i][j]表示i->j的最短路有几条。注意c至少开long long,但是实测double好像更快。
然后统计答案,对于k,枚举s,t,如果a[s][k]+a[k][t]=a[s][t],那么ans+=c[s][k]*c[k][t]/c[s][t]。
AC代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#define inf 1000000000
#define N 105
using namespace std;
int n,m,a[N][N]; double c[N][N];
int main(){
scanf("%d%d",&n,&m); int i,j,k;
for (i=1; i<=n; i++)
for (j=1; j<=n; j++) a[i][j]=inf;
for (i=1; i<=m; i++){
int x,y,z; scanf("%d%d%d",&x,&y,&z);
a[x][y]=a[y][x]=z; c[x][y]=c[y][x]=1;
}
for (k=1; k<=n; k++)
for (i=1; i<=n; i++) for (j=1; j<=n; j++){
if (a[i][k]+a[k][j]<a[i][j]){
a[i][j]=a[i][k]+a[k][j]; c[i][j]=0;
}
if (a[i][k]+a[k][j]==a[i][j]) c[i][j]+=c[i][k]*c[k][j];
}
for (i=1; i<=n; i++) c[i][i]=0;
for (k=1; k<=n; k++){
double ans=0;
for (i=1; i<=n; i++) for (j=1; j<=n; j++)
if (a[i][k]+a[k][j]==a[i][j] && c[i][j]){
ans+=c[i][k]*c[k][j]/c[i][j];
}
printf("%.3f\n",ans);
}
return 0;
}
by lych
2016.2.16