简单最短路计数。
#include#define ll long longusing namespace std;#define D doubleconst int N=305,M=100005;int to[M],ne[M],hd[N],Man[N][N];int n,m,d[N][N];ll f[N][N];D ans[M];inline void BFS(int x){ queue q; int y; d[x][x]=f[x][x]=1; q.push(x); while(!q.empty()){ y=q.front(),q.pop(); for(int i=hd[y];i;i=ne[i]) if(!d[x][to[i]]){ d[x][to[i]]=d[x][y]+1; f[x][to[i]]=f[x][y]; q.push(to[i]); } else if(d[x][to[i]]>d[x][y]) f[x][to[i]]+=f[x][y]; } for(int i=1;i<=n;i++) d[x][i]--;}inline void solve(){ for(int i=1;i<=n;i++) BFS(i); for(int i=1;i<=n;i++) for(int j=hd[i];j;j=ne[j]){ int u=i,v=to[j]; for(int a=1;a<=n;a++) for(int b=1;b<=n;b++) if(Man[a][b]&&f[a][b]&&d[a][u]+d[v][b]+1==d[a][b]) ans[j>>1]+=f[a][u]*f[v][b]*(ll)Man[a][b]/(D)f[a][b]; }}int main(){ scanf("%d%d",&n,&m); int uu,vv; for(int i=1;i<=m;i++){ scanf("%d%d",&uu,&vv); to[2*i]=vv,ne[2*i]=hd[uu],hd[uu]=2*i; to[2*i+1]=uu,ne[2*i+1]=hd[vv],hd[vv]=2*i+1; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&Man[i][j]); solve(); for(int i=1;i<=m;i++) printf("%.1lf\n",ans[i]); return 0;}