图论(floyd算法):NOI2007 社交网络

[NOI2007] 社交网络

★★   输入文件:network1.in   输出文件:network1.out   简单对比
时间限制:1 s  
内存限制:128 MB

【问题描述】

在社交网络(social
network)的研究中,我们常常使用图论概念去解释一些社会现象。不妨看这样的一个问题。在一个社交圈子里有n个人,人与人之间有不同程度的关系。我

们将这个关系网络对应到一个n个结点的无向图上,两个不同的人若互相认识,则在他们对应的结点之间连接一条无向边,并附上一个正数权值c,c越小,表示两
个人之间的关系越密切。

我们可以用对应结点之间的最短路长度来衡量两个人s和t之间的关系密切程度,注意到最短路径上的其他结点为s和t的联系提供了某种便利,
即这些结点对于s 和t之间的联系有一定的重要程度。我们可以通过统计经过一个结点v的最短路径的数目来衡量该结点在社交网络中的重要程度。

考虑到两个结点A和B之间可能会有多条最短路径。我们修改重要程度的定义如下:

令Cs,t表示从s到t的不同的最短路的数目,Cs,t(v)表示经过v从s到t的最短路的数目;则定义

I(v)=∑s≠v,t≠vCs,t(v)Cs,t

为结点v在社交网络中的重要程度。

为了使I(v)和Cs,t(v)有意义,我们规定需要处理的社交网络都是连通的无向图,即任意两个结点之间都有一条有限长度的最短路径。

现在给出这样一幅描述社交网络s的加权无向图,请你求出每一个结点的重要程度。

【输入文件】

输入文件中第一行有两个整数,n和m,表示社交网络中结点和无向边的数目。在无向图中,我们将所有结点从1到n进行编号。

接下来m行,每行用三个整数a, b, c描述一条连接结点a和b,权值为c的无向边。注意任意两个结点之间最多有一条无向边相连,无向图中也不会出现自环(即不存在一条无向边的两个端点是相同的结点)。

【输出文件】

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

【样例输入】

4 4

1 2 1

2 3 1

3 4 1

4 1 1

【样例输出】

1.000

1.000

1.000

1.000

【样例说明】

社交网络如下图所示。

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

【评分方法】

本题没有部分分,仅当你的程序计算得出的各个结点的重要程度与标准输出相差不超过0.001时,才能得到测试点的满分,否则不得分。

【数据规模和约定】

    • 50%的数据中:n ≤10,m ≤45
    • 100%的数据中:n ≤100,m ≤4 500,任意一条边的权值c是正整数,满足:1 ≤c ≤1 000。
    • 所有数据中保证给出的无向图连通,且任意两个结点之间的最短路径数目不超过10^10。

  floyd算法暴力就可以了,需要想清楚自己到自己的情况。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 const int maxn=110;
 6 long long G[maxn][maxn];
 7 long long E[maxn][maxn];
 8 int n,m;
 9 int main(){
10 #ifndef ONLINE_JUDGE
11     freopen("network1.in","r",stdin);
12     freopen("network1.out","w",stdout);
13 #endif
14     scanf("%d%d",&n,&m);
15     for(int i=1;i<=n;i++)
16         for(int j=1;j<=n;j++){
17             E[i][j]=i==j?0:(long long)1e18;
18             G[i][j]=1;
19         }
20     for(int i=1,a,b,c;i<=m;i++){
21         scanf("%d%d%d",&a,&b,&c);
22         E[a][b]=c;E[b][a]=c;
23         G[a][b]=G[b][a]=1;
24     }
25
26     for(int k=1;k<=n;k++)
27         for(int i=1;i<=n;i++)
28             for(int j=1;j<=n;j++){
29                 if(i==k||k==j||i==j)continue;
30                 if(E[i][k]+E[k][j]<E[i][j]){
31                     E[i][j]=E[i][k]+E[k][j];
32                     G[i][j]=G[i][k]*G[k][j];
33                 }
34                 else if(E[i][k]+E[k][j]==E[i][j])
35                     G[i][j]+=G[i][k]*G[k][j];
36             }
37
38     double ans=0;
39     for(int x=1;x<=n;x++){
40         ans=0.0;
41         for(int i=1;i<=n;i++)
42             for(int j=1;j<=n;j++)
43                 if(i!=j&&i!=x&&j!=x&&E[i][x]+E[x][j]==E[i][j])
44                     ans+=1.0*G[i][x]*G[x][j]/G[i][j];
45         printf("%.3f\n",ans);
46     }
47     return 0;
48 }
时间: 2024-11-17 12:13:42

图论(floyd算法):NOI2007 社交网络的相关文章

UVA 247 图论 floyd算法+递归遍历

先用floyd求出传递闭包,构造出一个新图,然后用递归的方法遍历图输出相互联通的节点. #include<iostream> #include<string> #include<algorithm> #include<map> #include<cstring> #include<vector> #include<cstdio> using namespace std; #define N 500 int d[N][N];

BZOJ 1491: [NOI2007]社交网络( floyd )

floyd...求最短路时顺便求出路径数. 时间复杂度O(N^3) ------------------------------------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; const int max

图论之最短路径floyd算法

Floyd算法是图论中经典的多源最短路径算法,即求任意两点之间的最短路径. 它可采用动态规划思想,因为它满足最优子结构性质,即最短路径序列的子序列也是最短路径. 举例说明最优子结构性质,上图中1号到5号的最短路径序列<1,2,4,5>,其子序列<1,2,4>也是最短路径. 在动态规划算法中,处于首要位置.且也是核心理念之一的就是状态的定义. 动态转移的基本思想可以认为是建立起某一状态和之前状态的一种转移表示. d[k][i][j]定义为"只能使用第1号到第k号点作为中间媒

图论之最短路01——最短路矩阵(FLOYD)算法

%======================================================== %最短路矩阵算法,FLOYD算法 %针对性:方案预算,能求出所有点之间的最短路(最小费用等) %======================================================== function D=zuiduanjulijuzhen(quanzhijuzhen) n=length(quanzhijuzhen); D=quanzhijuzhen; m

最短路径Dijkstra算法和Floyd算法整理、

转载自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 最短路径—Dijkstra算法和Floyd算法 Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法是很有代表性的最短路径算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹

最短路径—Dijkstra算法和Floyd算法

Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法是很有代表性的最短路径算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等.注意该算法要求图中不存在负权边. 问题描述:在无向图 G=(V,E) 中,假设每条边 E[i] 的长度为 w[i],找到由顶点 V0 到其余各点的最短路径.(单源最短路径) 2.算法

Floyd 算法求多源最短路径

Floyd算法: Floyd算法用来找出每对顶点之间的最短距离,它对图的要求是,既可以是无向图也可以是有向图,边权可以为负,但是不能存在负环. 基本算法: Floyd算法基于动态规划的思想,以 u 到 v 的最短路径至少经过前 k 个点为转移状态进行计算,通过 k 的增加达到寻找最短路径的目的.当 k 增加 1 时,最短路径要么不边,如果改变,必经过第 k 各点,也就是说当起点 u 到第 k 个点的最短距离加上第 k 个点到终点 v 的最短路径小于不经过第 k 个节点的最优最短路经长度的时候更新

1491: [NOI2007]社交网络

1491: [NOI2007]社交网络 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 881  Solved: 518[Submit][Status] Description Input 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.0

探求Floyd算法的动态规划本质

Floyd–Warshall(简称Floyd算法)是一种著名的解决任意两点间的最短路径(All Paris Shortest Paths,APSP)的算法.从表面上粗看,Floyd算法是一个非常简单的三重循环,而且纯粹的Floyd算法的循环体内的语句也十分简洁.我认为, 正是由于“Floyd算法是一种动态规划(Dynamic Programming)算法”的本质,才导致了Floyd算法如此精妙.因此,这里我将从Floyd算法的状态定义.动态转移方程以及滚动数组等重要方 面,来简单剖析一下图论中这