给出
n
≤
100
n\leq100
n≤100,
m
≤
4500
m\leq4500
m≤4500的无向图,权值
c
≤
1000
c\leq1000
c≤1000,然后求问对于每个点
v
v
v,求
I
(
v
)
=
∑
s
≠
v
,
s
≠
t
C
s
,
t
(
v
)
C
s
,
t
I(v)=\sum_{s≠ v,s≠ t}\frac{C_{s,t}(v)}{C_{s,t}}
I(v)=∑s̸=v,s̸=tCs,tCs,t(v),
C
s
,
t
C_{s,t}
Cs,t定义为
s
,
t
s,t
s,t路径上的最短路数,
C
s
,
t
(
v
)
C_{s,t}(v)
Cs,t(v)定义为经过
v
v
v的
s
,
t
s,t
s,t路径上最短路方案数。
由于
n
n
n很小,直接
f
l
o
y
d
floyd
floyd求出两点之间的最短距离,同时统计出所有点对的方案数。然后枚举每个点,再枚举所有的不为这个点的互异点对,计算这个点的贡献。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll INF=LONG_LONG_MAX;
const int N=105;
int mp[N][N];
ll f[N][N];
double ans[N];
int main() {
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) {
mp[i][j]=1e9;
}
}
for(int i=1;i<=m;i++) {
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
mp[u][v]=mp[v][u]=c;
f[u][v]=f[v][u]=1;
}
for(int k=1;k<=n;k++) {
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) {
if(mp[i][k]+mp[k][j]<mp[i][j]) {
mp[i][j]=mp[i][k]+mp[k][j];
f[i][j]=f[i][k]*f[k][j];
}
else if(mp[i][k]+mp[k][j]==mp[i][j]) {
f[i][j]+=f[i][k]*f[k][j];
}
}
}
}
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) {
if(i==j) continue;
for(int k=1;k<=n;k++) {
if(i==k||j==k) continue;
if(mp[i][k]+mp[k][j]==mp[i][j]) {
ans[k]+=1.0*f[i][k]*f[k][j]/f[i][j];
}
}
}
}
for(int i=1;i<=n;i++)
printf("%.3lf\n",ans[i]);
return 0;
}