[NOI2007]社交网络

本文介绍了一种基于Floyd算法的最短路径计算方法,并通过具体代码实例展示了如何利用该算法计算图中各节点的重要性。文章首先定义了d(u,v)表示从u到v的最短路径长度,w(u,v)表示最短路径数量,然后通过迭代更新最短路径长度和数量,最终计算出每个节点的重要程度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接
【分析】

  • 就是Floyd的最短路计数
  • d ( u , v ) d(u,v) d(u,v)表示从 u u u v v v的最短路长度, w ( u , v ) w(u,v) w(u,v)表示最短路的数量
  • 分两种情况讨论
  • d i s ( i , j ) > d i s ( i , k ) + d i s ( k , j ) dis(i,j)>dis(i,k)+dis(k,j) dis(i,j)>dis(i,k)+dis(k,j),则令 w ( i , j ) = w ( i , k ) × w ( k , j ) w(i,j)=w(i,k) \times w(k,j) w(i,j)=w(i,k)×w(k,j),同时更新最短路长度
  • d i s ( i , j ) = d i s ( i , k ) + d i s ( k , j ) dis(i,j)=dis(i,k)+dis(k,j) dis(i,j)=dis(i,k)+dis(k,j),则令 w ( i , j ) + = w ( i , k ) × w ( k , j ) w(i,j)+=w(i,k) \times w(k,j) w(i,j)+=w(i,k)×w(k,j)
  • 然后根据题目中的公式,算出每个结点的重要程度

【代码】

#include<bits/stdc++.h>
#define ll long long

using namespace std;

const int maxn = 110;

int n, m;
ll w[maxn][maxn];
int d[maxn][maxn];
double ans[maxn];

int main()
{
	scanf("%d%d", &n, &m);
	memset(d, 0x3f, sizeof d);
	for(int i = 1; i <= m; i++)
	{
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		d[a][b] = d[b][a] = c;
		w[a][b] = w[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(i == j || j == k || i == k)
					continue;
				if(d[i][j] == d[i][k] + d[k][j])
					w[i][j] += w[i][k] * w[k][j];
				if(d[i][j] > d[i][k] + d[k][j])
				{
					d[i][j] = d[i][k] + d[k][j];
					w[i][j] = w[i][k] * w[k][j];
				}
			}
	}
	
	for(int k = 1; k <= n; k++)
	{
		for(int i = 1; i <= n; i++)
			for(int j = 1; j <= n; j++)
			{
				if(i == j || j == k || i == k)
					continue;
				if(d[i][j] == d[i][k] + d[k][j])
					ans[k] += (double) (w[i][k] * w[k][j]) / w[i][j];
			}
	}
	
	for(int i = 1; i <= n; i++)
		printf("%.3lf\n", ans[i]);
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值