BZOJ 1491: [NOI2007]社交网络(Floyd+暴力乱搞)

题面:

  https://www.lydsy.com/JudgeOnline/problem.php?id=1491

题解:
  先看数据范围,n<=100。。欸可以乱搞了

  首先因为小学学过的乘法原理,a->b有n种走法,b->c有m种走法,那么a->c有n*m种走法。

  那么我们就用一个类似邻接矩阵的p矩阵来存走法,p[i][j]表示在最短路的前提下,从i到j的走法。

  那么在用floyd跑最短路的时候,如果可以松弛,就用p[i][k]*p[k][j]来更新p[i][j];如果不能松弛,就判断一下如果相等,就由于加法原理,给p[i][j]加上p[i][k]*p[k][j]。

代码:

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 typedef long long ll;
 6 typedef double dd;
 7 const int maxn=110;
 8 int n,m,u,v,w;
 9 ll g[maxn][maxn],p[maxn][maxn];
10 dd ans[maxn];
11 
12 int main(){
13     memset(g,0x3f3f3f3f,sizeof(g));
14     scanf("%d%d",&n,&m);
15     for(int i=1;i<=m;i++) 
16         scanf("%d%d%d",&u,&v,&w),g[u][v]=g[v][u]=w,p[u][v]=p[v][u]=1;
17     for(int k=1;k<=n;k++)
18         for(int i=1;i<=n;i++)
19             for(int j=1;j<=n;j++)
20                 if(g[i][j]>g[i][k]+g[k][j])
21                     g[i][j]=g[i][k]+g[k][j],
22                     p[i][j]=p[i][k]*p[k][j];
23                 else if(g[i][j]==g[i][k]+g[k][j])
24                     p[i][j]+=p[i][k]*p[k][j];
25     for(int k=1;k<=n;k++)
26         for(int i=1;i<=n;i++)
27             for(int j=1;j<=n;j++)
28                 if(i!=j&&j!=k&&i!=k&&g[i][k]+g[k][j]==g[i][j])
29                     ans[k]+=(dd)p[i][k]*p[k][j]/p[i][j];
30     for(int i=1;i<=n;i++)    
31         printf("%.3lf\n",ans[i]);
32     return 0;    
33 }

 

 

posted @ 2018-04-17 13:40  Jack_the_Ripper  阅读(123)  评论(0编辑  收藏  举报