Description

在社交网络(socialnetwork)的研究中,我们常常使用图论概念去解释一些社会现象。不妨看这样的一个问题。在一个社交圈子里有n个人,人与人之间有不同程度的关系。我们将这个关系网络对应到一个n个结点的无向图上,两个不同的人若互相认识,则在他们对应的结点之间连接一条无向边,并附上一个正数权值c,c越小,表示两个人之间的关系越密切。我们可以用对应结点之间的最短路长度来衡量两个人s和t之间的关系密切程度,注意到最短路径上的其他结点为s和t的联系提供了某种便利,即这些结点对于s和t之间的联系有一定的重要程度。我们可以通过统计经过一个结点v的最短路径的数目来衡量该结点在社交网络中的重要程度。考虑到两个结点A和B之间可能会有多条最短路径。我们修改重要程度的定义如下:令Cs,t表示从s到t的不同的最短路的数目,Cs,t(v)表示经过v从s到t的最短路的数目;则定义为结点v在社交网络中的重要程度。为了使I(v)和Cs,t(v)有意义,我们规定需要处理的社交网络都是连通的无向图,即任意两个结点之间都有一条有限长度的最短路径。现在给出这样一幅描述社交网络的加权无向图,请你求出每一个结点的重要程度。

Input

输入第一行有两个整数n和m,表示社交网络中结点和无向边的数目。在无向图中,我们将所有结点从1到n进行编号。接下来m行,每行用三个整数a,b,c描述一条连接结点a和b,权值为c的无向边。注意任意两个结点之间最多有一条无向边相连,无向图中也不会出现自环(即不存在一条无向边的两个端点是相同的结点)。n≤100;m≤4500 ,任意一条边的权值 c 是正整数,满足:1≤c≤1000。所有数据中保证给出的无向图连通,且任意两个结点之间的最短路径数目不超过 10^10

Output

输出包括n行,每行一个实数,精确到小数点后3位。第i行的实数表示结点i在社交网络中的重要程度。

Sample Input

4 4
1 2 1
2 3 1
3 4 1
4 1 1

Sample Output

1.000
1.000
1.000
1.000

HINT

社交网络如下图所示。

对于 1 号结点而言,只有 2 号到 4 号结点和 4 号到 2 号结点的最短路经过 1 号结点,而 2 号结点和 4 号结点之间的最短路又有 2 条。因而根据定义,1 号结点的重要程度计算为 1/2 + 1/2 = 1 。由于图的对称性,其他三个结点的重要程度也都是 1 。

题解

从数据约定来看,$n<=100$,明显可以用$floyd$,而且题目要求算某个中间点的重要程度,也比较符合$floyd$以中间点划分阶段的思想。
这道题主要就是要推理出最短路的条数怎么算。
令$w[i,j]$为从点$i$到点$j$的最短路径条数,$f[i,j]$为最短路。则根据最短路径拥有最优子结构的性质和乘法原理,我们可以得出:
$$w[i,j]=w[i,j]+w[i,k]*w[k,j](f[i,j]=f[i,k]+f[k,j])$$
$$w[i,j]=w[i,k]*w[k,j](f[i,j]>f[i,k]+f[k,j])$$
再令$g[i,j,k]$为从点$i$到点$j$且经过点$k$的最短路径的条数。也正是根据这个最优子结构,我们又可以明白:
$$g[i,j,k]=w[i,k]*w[k,j](f[i,j]=f[i,k]=f[k,j])$$
然后根据题目所给的公式统计答案就行了。

 //It is made by Awson on 2017.9.25
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define sqr(x) ((x)*(x))
#define Abs(x) ((x) < 0 ? (-(x)) ? (x))
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const int N = ;
LL Read() {
LL sum = ;
char ch = getchar();
while (ch < '' || ch > '') ch = getchar();
while (ch >= '' && ch <= '') sum = (sum<<)+(sum<<)+ch-, ch = getchar();
return sum;
} LL n, m, u, v, c;
LL f[N+][N+];
LL cnt[N+][N+];
double ans[N+]; void work() {
n = Read(), m = Read();
memset(f, /, sizeof(f));
while (m--) {
u = Read(), v = Read(), c = Read();
if (f[u][v] > c) {
f[u][v] = f[v][u] = c;
cnt[u][v] = cnt[v][u] = ;
}
else if (f[u][v] == c)
cnt[u][v] = ++cnt[v][u];
}
for (LL k = ; k <= n; k++)
for (LL i = ; i <= n; i++)
for (LL j = ; j <= n; j++)
if (k != j && k != i && i != j) {
if (f[i][k]+f[k][j] < f[i][j]) {
f[i][j] = f[i][k]+f[k][j];
cnt[i][j] = cnt[i][k]*cnt[k][j];
}
else if (f[i][k]+f[k][j] == f[i][j])
cnt[i][j] += cnt[i][k]*cnt[k][j];
}
for (LL k = ; k <= n; k++)
for (LL i = ; i <= n; i++)
for (LL j = ; j <= n; j++)
if (k != j && k != i && i != j)
if (f[i][k]+f[k][j] == f[i][j])
ans[k] += (double)(cnt[i][k]*cnt[k][j])/(double)(cnt[i][j]);
for (LL i = ; i <= n; i++)
printf("%.3lf\n", ans[i]);
}
int main() {
freopen("bestlink.in", "r", stdin);
freopen("bestlink.out", "w", stdout);
work();
return ;
}

[NOI 2007]社交网络的更多相关文章

  1. 解题:NOI 2007 社交网络

    题面 先跑一边Floyd乘法原理统计任意两点间最短路数目,然后再枚举一次按照题意即可求出答案,会写那道JSOI2007就会这个 #include<cstdio> #include<c ...

  2. 【NOI 2007】 社交网络

    [题目链接] 点击打开链接 [算法] 首先,跑floyd,计算最短路和最短路径数 然后,计算答案,枚举k,s,t,若dist[s][k] + dist[k][t] = dist[s][t], 那么,点 ...

  3. 【BZOJ 1494】【NOI 2007】生成树计数

    http://www.lydsy.com/JudgeOnline/problem.php?id=1494 这道题..因为k很小,而且我们只关心连续的k个节点的连通性,所以把连续的k个点轮廓线上的连通性 ...

  4. 【BZOJ 1492】【NOI 2007】货币兑换Cash

    这是道CDQ分治的例题: $O(n^2)$的DP: f [1]←S* Rate[1] / (A[1] * Rate[1] + B[1]) Ans←SFor i ← 2 to n For j ←1 to ...

  5. 线性代数(矩阵乘法):NOI 2007 生成树计数

    这道题就是深搜矩阵,再快速幂. #include <iostream> #include <cstring> #include <cstdio> #include ...

  6. [NOI 2007]货币兑换Cash

    Description 题库链接 (按我的语文水平完全无 fa♂ 概括题意,找了 hahalidaxin 的题意简述... 有 \(AB\) 两种货币,每天可以可以付 \(IP_i\) 元,买到 \( ...

  7. NOI 2007 货币兑换Cash (bzoj 1492) - 斜率优化 - 动态规划 - CDQ分治

    Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券(以下 简称B券).每个持有金券的顾客都有一个自己的帐户.金券的数目可以是一个 ...

  8. dp式子100个……

    1.        资源问题1-----机器分配问题F[I,j]:=max(f[i-1,k]+w[i,j-k]) 2.        资源问题2------01背包问题F[I,j]:=max(f[i- ...

  9. dp方程

    1.        资源问题1 -----机器分配问题 F[I,j]:=max(f[i-1,k]+w[i,j-k]) 2.        资源问题2 ------01背包问题   F[I,j]:=ma ...

随机推荐

  1. Java基础学习笔记十一 Eclipse开发工具

    Eclipse是功能强大Java集成开发工具.它可以极大地提升我们的开发效率.可以自动编译,检查错误.在公司中,使用的就是Eclipse进行开发. Eclipse的下载.安装.卸载 下载 http:/ ...

  2. Leetcode 19——Remove Nth Node From End of List

    Given a linked list, remove the nth node from the end of list and return its head. For example, Give ...

  3. PTA的使用简介

    PTA(Programming Teaching Assistant)是PAT(Programming Ability Test)的配套练习平台. 1.关于PAT PAT(Programming Ab ...

  4. 第九条:覆盖equals方法时总要覆盖hashCode方法

    Object类的hashCode方法: public native int hashCode();   是一个本地方法. 其中这个方法的主要注释如下: Whenever it is invoked o ...

  5. java实现红包的分配算法

    个人推测,微信红包在发出的时候已经分配好金额.比如一个10元的红包发给甲乙丙三个人,其实在红包发出去的时候,已经确定了第一个会领取多少,第二个会领取多少金额. 而不是在领取的时候才计算的.下面贴出实现 ...

  6. 容器化的 DevOps 工作流

    对于 devops 来说,容器技术绝对是我们笑傲江湖的法宝.本文通过一个小 demo 来介绍如何使用容器技术来改进我们的 devops 工作流. devops 的日常工作中难免会有一些繁琐的重复性劳动 ...

  7. float和position

    float float是欺骗父元素,让其父元素误以为其高度塌陷了,但float元素本身仍处于文档流中,文字会环绕着float元素,不会被遮蔽. absolute 但absolute其实已经不能算是欺骗 ...

  8. Delaunay三角化算法

    参考:<平面域中的Delaunay三角算法>

  9. python开发:python字符串操作方法

    name = "my \tname is {name} and i am {year} old" capitalize:第一个单词的首字母大写的方法 print(name.capi ...

  10. Help Jimmy ~poj-1661 基础DP

    Help Jimmy" 是在下图所示的场景上完成的游戏. 场景中包括多个长度和高度各不相同的平台.地面是最低的平台,高度为零,长度无限. Jimmy老鼠在时刻0从高于所有平台的某处开始下落, ...