[SHOI2009] 交通网络
简单最短路计数。
#include<bits/stdc++.h> #define ll long long using namespace std; #define D double const 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<int> 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; }
我爱学习,学习使我快乐