【NOI 2007】 社交网络

【题目链接】

           点击打开链接

【算法】

           首先,跑floyd,计算最短路和最短路径数

           然后,计算答案,枚举k,s,t,若dist[s][k] + dist[k][t] = dist[s][t],

                                                    那么,点对(s,t)对答案k的”贡献“就是c[s][k]*c[k][t]/c[s][t]

【代码】

         

#include<bits/stdc++.h>
using namespace std;
#define MAXN 110
const int INF = 1e9;

int i,j,n,m,u,v,w;
double ans[MAXN];
long long g[MAXN][MAXN],c[MAXN][MAXN];

inline void floyd()
{
        int i,j,k;
        for (k = 1; k <= n; k++)
        {
                for (i = 1; i <= n; i++)
                {
                        if (i == k) continue;
                        for (j = 1; j <= n; j++)
                        {
                                if (i == j || k == j) continue;
                                if (g[i][k] + g[k][j] < g[i][j])
                                {
                                        g[i][j] = g[i][k] + g[k][j];
                                        c[i][j] = c[i][k] * c[k][j];
                                }
                                else if (g[i][k] + g[k][j] == g[i][j]) c[i][j] += c[i][k] * c[k][j];
                        }
                }        
        }        
}
inline void calc()
{
        int k,s,t;
        for (k = 1; k <= n; k++)
        {
                for (s = 1; s <= n; s++)
                {
                        for (t = 1; t <= n; t++)
                        {
                                if (s == t) continue;
                                if (g[s][k] + g[k][t] == g[s][t])
                                {
                                        if (c[s][t]) 
                                                ans[k] += 1.0 * c[s][k] * c[k][t] / c[s][t];
                                }
                        }
                }
        }    
}

int main() {
        
        scanf("%d%d",&n,&m);
        for (i = 1; i <= n; i++)
        {
                for (j = 1; j <= n; j++)
                {
                        g[i][j] = INF;
                }
        }
        while (m--)
        {
                scanf("%d%d%d",&u,&v,&w);
                g[u][v] = g[v][u] = w;
                c[u][v] = c[v][u] = 1;
        }
        
        floyd();
        calc();
        
        for (i = 1; i <= n; i++) printf("%.3lf\n",ans[i]);
        
        return 0;
    
}


           

 

转载于:https://www.cnblogs.com/evenbao/p/9196321.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值