洛谷——P2047 [NOI2007]社交网络

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\n",im[i]);
    
    return 0;
}

 

posted @ 2018-10-17 14:44  清风我已逝  阅读(242)  评论(0编辑  收藏  举报