【Floyd】BZOJ1491: [NOI2007]社交网络
Description
Solution
n<=100自然联想Floyd
设两个数组d[n][n]存最短距离,t[n][n]存最短路径条数
更新d的时候顺便更新t,乘法原理
1 if(d[i][j]>d[i][k]+d[k][j]){ 2 d[i][j]=d[i][k]+d[k][j]; 3 t[i][j]=t[i][k]*t[k][j]; 4 } 5 else if(d[i][j]==d[i][k]+d[k][j]) 6 t[i][j]+=t[i][k]*t[k][j];
再统计答案
1 if(d[i][j]==d[i][k]+d[k][j]) 2 c[k]+=(double)(t[i][k]*t[k][j])/t[i][j];
感觉Floyd也就能做这些事。。
Code
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #define ll long long 5 const int maxn=105; 6 7 ll d[maxn][maxn],t[maxn][maxn]; 8 int n,m; 9 double c[maxn]; 10 11 int main(){ 12 scanf("%d%d",&n,&m); 13 int u,v,w; 14 memset(d,127/3,sizeof(d)); 15 for(int i=1;i<=n;i++) 16 d[i][i]=0,t[i][i]=1; 17 18 for(int i=1;i<=m;i++){ 19 scanf("%d%d%d",&u,&v,&w); 20 if(w<d[u][v]){ 21 d[u][v]=d[v][u]=w; 22 t[u][v]=t[v][u]=1; 23 } 24 else if(w==d[u][v]){ 25 t[u][v]++; 26 t[v][u]++; 27 } 28 } 29 30 for(int k=1;k<=n;k++) 31 for(int i=1;i<=n;i++) 32 for(int j=1;j<=n;j++)if(i!=j&&i!=k&&j!=k){ 33 if(d[i][j]>d[i][k]+d[k][j]){ 34 d[i][j]=d[i][k]+d[k][j]; 35 t[i][j]=t[i][k]*t[k][j]; 36 } 37 else if(d[i][j]==d[i][k]+d[k][j]) 38 t[i][j]+=t[i][k]*t[k][j]; 39 } 40 41 memset(c,0,sizeof(c)); 42 for(int i=1;i<=n;i++) 43 for(int j=1;j<=n;j++) 44 for(int k=1;k<=n;k++)if(i!=j&&i!=k&&j!=k){ 45 if(d[i][j]!=d[i][k]+d[k][j]) continue; 46 c[k]+=(double)t[i][k]*t[k][j]/t[i][j]; 47 } 48 49 for(int i=1;i<=n;i++) 50 printf("%.3lf\n",c[i]); 51 return 0; 52 }