P2047 [NOI2007]社交网络
$Floyd$,一眼看到就是他(博主是不小心瞄到了这个题的标签吧qwq)
这个题目只要预处理出$S$到$T$的最短路的条数即可,类似$Spfa$的更新方法
如果当前枚举的$k$可以更新$i$到$j$的最短路,那么就更新最短路,同时$i$到$j$的最短路条数更新为$p[i][k]*p[k][j]$根据乘法原理,$p[i][j]$表示$i$到$j$的最短路条数
最后统计一下就可以了,也是$N^3$暴力枚举
注意:要开$long$$long$
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define N 105 #define LL long long using namespace std; int n,m; LL d[N][N],p[N][N]; double im[N]; int main() { scanf("%d%d",&n,&m); memset(d,0x7f,sizeof(d)); for(int u,v,w,i=1;i<=m;i++){ scanf("%d%d%d",&u,&v,&w); d[u][v]=min(d[u][v],(LL)w); d[v][u]=min(d[v][u],(LL)w); p[u][v]=p[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(d[i][k]==d[0][0]&&d[k][j]==d[0][0]) continue; if(d[i][k]+d[k][j]<d[i][j]) d[i][j]=d[i][k]+d[k][j],p[i][j]=p[i][k]*p[k][j]; else if(d[i][k]+d[k][j]==d[i][j]) p[i][j]+=p[i][k]*p[k][j]; } for(int v=1;v<=n;v++){ for(int s=1;s<=n;s++){ for(int t=1;t<=n;t++){ if(v==s||s==t||v==t) continue; if(d[s][v]+d[v][t]==d[s][t]) im[v]+=(1.0*p[s][v]*p[v][t])/(double)p[s][t]; } } } for(int i=1;i<=n;i++) printf("%.3lf ",im[i]); return 0; }