这题你看n很小,直接floyd就好了
f[i][j]表示i到j的最短路
注意到
f[i][j]=min{f[i][k]+f[k][j]}
然后我们设c[i][j]为i到j之间的路径长度为f[i][j]的有多少
假设有f[i][k]+f[k][j]=f[i][j]的话
因为i到k之间路径长度为f[i][k]的可能有多条,k到j之间路径长度为f[k][j]的可能有多条
那么根据乘法原理(好像是这东西),乘起来就是i到j之间路径长度为f[i][j]的总条数了
然后怎么统计I(v)的话,看代码吧
1 #include<cstdio> 2 #define inf 1*1e9 3 int n,m,f[105][105]; 4 double cnt[105][105]; 5 double ans[105]; 6 int main() { 7 scanf("%d%d",&n,&m); 8 for(int i=1;i<=n;i++) 9 for(int j=1;j<=n;j++) 10 f[i][j]=(i==j)?0:inf; 11 for(int i=1;i<=m;i++) { 12 int u,v,w; 13 scanf("%d%d%d",&u,&v,&w); 14 f[u][v]=f[v][u]=w; 15 cnt[u][v]=cnt[v][u]=1; 16 } 17 for(int k=1;k<=n;k++) 18 for(int i=1;i<=n;i++) 19 if(i!=k) 20 for(int j=1;j<=n;j++) 21 if(k!=j&&i!=j) { 22 if(f[i][k]+f[k][j]<f[i][j]) { 23 f[i][j]=f[i][k]+f[k][j]; 24 cnt[i][j]=cnt[i][k]*cnt[k][j]; 25 }else 26 if(f[i][k]+f[k][j]==f[i][j]) 27 cnt[i][j]+=cnt[i][k]*cnt[k][j]; 28 } 29 // for(int i=1;i<=n;i++) 30 // for(int j=1;j<=n;j++) 31 // printf("%d %d %d\n",i,j,f[i][j]); 32 for(int k=1;k<=n;k++) 33 for(int i=1;i<=n;i++) 34 if(i!=k) 35 for(int j=1;j<=n;j++) 36 if(k!=j&&i!=j) { 37 if(f[i][k]+f[k][j]==f[i][j]&&cnt[i][j]) 38 ans[k]+=1.000000*cnt[i][k]*cnt[k][j]/cnt[i][j]; 39 } 40 for(int i=1;i<=n;i++) 41 printf("%.3f\n",ans[i]); 42 }