P2047 [NOI2007] 社交网络

/*
floyd 任意两点之间的距离 
检测 中间的一个点 d[][]+d[][]==d[][]  
cnt[][] -> [][]之间的条数 
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
//#include<queue>
//#include<vector>
#include<bits/stdc++.h>
#define ll long long
#define ddd printf("-----------------------\n");
using namespace std;
const int maxn=2e3+10 ;

int n,m;
ll dis[maxn][maxn],cnt[maxn][maxn];
double ans[maxn];

int main()
{
    ios::sync_with_stdio(false);
    
    memset(dis,0x3f,sizeof(dis));
    cin>>n>>m;
    for(int i=1;i<=n;i++) dis[i][i]=0;
    
    for(int i=1;i<=m;i++){
        int a,b,val;cin>>a>>b>>val;
        dis[a][b]=dis[b][a]=val;
        cnt[a][b]=cnt[b][a]=1;
    }
    
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                if(dis[i][j]>dis[i][k]+dis[k][j])
                {
                    dis[i][j]=dis[i][k]+dis[k][j];
                    cnt[i][j]=cnt[i][k]*cnt[k][j];
                }
                else if(dis[i][j]==dis[i][k]+dis[k][j]) cnt[i][j]+=cnt[i][k]*cnt[k][j];        
            }
                
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                if(k==i&&k==j&&i==j) continue;
                if(dis[i][j]==dis[i][k]+dis[k][j])
                    ans[k]+=(1.0*cnt[i][k]*cnt[k][j])/cnt[i][j];
                
            }
                
    for(int i=1;i<=n;i++) printf("%.3lf\n",ans[i]);
    return 0;
}

 

posted @ 2023-09-17 16:06  JMXZ  阅读(12)  评论(0)    收藏  举报