zoukankan      html  css  js  c++  java
  • [NOI2007]社交网络

    题目描述

    给定 n 个点 m 条边的无向图,定义 $C_{s,t}$ 为 $s 到 t $的最短路条数,$C_{s,t(u)}$ 为经过$ u 的 s 到 t $的最短路条数。对于每个节点$ u$,求$I(u) =∑_{s,t}C_{s,t(u)}/C_{s,t} $

    思路

    $floyd$求最短路,$dist数组表示最短路长度,sum表示最短路数量,对于i,我们枚举s,t,若dis(s,i)+dis(i,t)=dis(s,t),则可以把答案加到I(i)上$。

    code

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long LL;
    const int N=110;
    LL dist[N][N];
    LL sum[N][N];
    int n,m;
    double I[N];
    
    int main()
    {
        scanf("%d%d",&n,&m);
        memset(dist,127,sizeof(dist));
        for(int i=1;i<=m;i++)
        {
            int x,y;
            LL z;scanf("%d%d%lld",&x,&y,&z);
            sum[x][y]=sum[y][x]=1;
            dist[x][y]=dist[y][x]=min(z,dist[x][y]);
        }
        for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        {
            if(dist[i][k]==dist[0][0]&&dist[k][j]==dist[0][0])continue;
            if(dist[i][j]==dist[i][k]+dist[k][j])
            {
                sum[i][j]+=sum[i][k]*sum[k][j];
                continue;
            }
            if(dist[i][j]>dist[i][k]+dist[k][j])
            {
                sum[i][j]=sum[i][k]*sum[k][j];
                dist[i][j]=dist[i][k]+dist[k][j];
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int s=1;s<=n;s++)
            for(int t=1;t<=n;t++)
            {
                if(s!=i&&i!=t&&s!=t&&sum[s][t]&&dist[s][t]==dist[s][i]+dist[i][t])
                I[i]+=(1.0*sum[s][i]*sum[i][t])/(1.0*sum[s][t]);
            }
        }
        for(int i=1;i<=n;i++)printf("%.3lf
    ",I[i]);
    }

     

  • 相关阅读:
    Tree MapByFold
    Tree DepthByFold
    Tree SizeByFold
    Tree MaximumByFold
    Tree Fold
    Tree Map
    Tree Depth
    Tree Maximum
    Tree Size
    Tree
  • 原文地址:https://www.cnblogs.com/THRANDUil/p/11618360.html
Copyright © 2011-2022 走看看