题解:Floyd应用
d[i][j]两点最短路
c[i][j]两点最短路条数
转移
若d[i][k]+d[k][j]<d[i][j]则c[i][j]=c[i][k]*c[k][j]
若d[i][k]+d[k][j]==d[i][j]则c[i][j]+=c[i][k]*c[k][j];
统计答案时当d[s][v]+d[v][t]==d[s][t]则对答案有贡献c[s][v]*c[v][t]/c[s][t]
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=109;
const int oo=1000000000;
int n,m;
int d[maxn][maxn];
long long c[maxn][maxn];
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
d[i][j]=oo;
}
}
for(int i=1;i<=n;++i)d[i][i]=0;
while(m--){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
d[x][y]=d[y][x]=z;
c[x][y]=c[y][x]=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)||(i==k)||(j==k))continue;
if(d[i][k]+d[k][j]<d[i][j]){
d[i][j]=d[i][k]+d[k][j];
c[i][j]=c[i][k]*c[k][j];
}else if(d[i][k]+d[k][j]==d[i][j]){
c[i][j]+=c[i][k]*c[k][j];
}
}
}
}
for(int k=1;k<=n;++k){
double ans=0;
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
if((i==j)||(i==k)||(j==k))continue;
if(d[i][k]+d[k][j]==d[i][j]){
ans+=1.0*c[i][k]*c[k][j]/c[i][j];
}
}
}
printf("%.3f\n",ans);
}
return 0;
}