【NOI2007】 社交网络
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
社交网络 问题描述 在社交网络(social network)的研究中,我们常常使用图论概念去解释一些 社会现象。 不妨看这样的一个问题。在一个社交圈子里有 n 个人,人与人之间有不同程 度的关系。我们将这个关系网络对应到一个 n 个结点的无向图上,两个不同的人 若互相认识, 则在他们对应的结点之间连接一条无向边, 并附上一个正数权值 c, c 越小,表示两个人之间的关系越密切。 我们可以用对应结点之间的最短路长度来衡量两个人 s 和 t 之间的关系密切 程度,注意到最短路径上的其他结点为 s 和 t 的联系提供了某种便利,即这些结 点对于 s 和 t 之间的联系有一定的重要程度。我们可以通过统计经过一个结点 v 的最短路径的数目来衡量该结点在社交网络中的重要程度。 考虑到两个结点 A 和 B 之间可能会有多条最短路径。 我们修改重要程度的定 义如下: 令 Cs,t 表示从 s 到 t 的不同的最短路的数目, s,t(v)表示经过 v 从 s 到 t 的最短 C 路的数目;则定义 I (v ) = C s , t (v ) ∑ -------------- s≠v,t ≠v C s, t 为结点 v 在社交网络中的重要程度。 为了使 I(v)和 Cs,t(v)有意义,我们规定需要处理的社交网络都是连通的无向 图,即任意两个结点之间都有一条有限长度的最短路径。 现在给出这样一幅描述社交网络的加权无向图,请你求出每一个结点的重要 程度。 输入文件 输入文件中第一行有两个整数,n 和 m,表示社交网络中结点和无向边的数 目。在无向图中,我们将所有结点从 1 到 n 进行编号。 接下来 m 行,每行用三个整数 a, b, c 描述一条连接结点 a 和 b,权值为 c 的 无向边。注意任意两个结点之间最多有一条无向边相连,无向图中也不会出现自 环(即不存在一条无向边的两个端点是相同的结点) 。 输出文件 输出文件包括 n 行,每行一个实数,精确到小数点后 3 位。第 i 行的实数表 示结点 i 在社交网络中的重要程度。 输入样例 44 121 231 341 411 输出样例 1.000 1.000 1.000 1.000 样例说明 社交网络如下图所示。 对于 1 号结点而言,只有 2 号到 4 号结点和 4 号到 2 号结点的最短路经过 1 号结点,而 2 号结点和 4 号结点之间的最短路又有 2 条。因而根据定义,1 号结 点的重要程度计算为1 1 。由于图的对称性,其他三个结点的重 -- + -- =1 2 2 要程度也都是 1。 评分方法 本题没有部分分,仅当你的程序计算得出的各个结点的重要程度与标准输出 相差不超过0.001时,才能得到测试点的满分,否则不得分。 数据规模和约定 50%的数据中:n ≤ 10,m ≤ 45 100%的数据中:n ≤ 100,m ≤ 4 500,任意一条边的权值 c 是正整数,满 足:1 ≤ c ≤ 1 000。 所有数据中保证给出的无向图连通,且任意两个结点之间的最短路径数目不 超过 1010。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 (* 2 Problem: NOI2007 社交网络 3 Author: chenyang 4 Time: 2012.5.24 4:34 pm 5 State: 90分 6 Memo: 统计最短路条数 7 Lesson: 在floyed的同时进行统计,不必dfs搜索 8 *) 9 program network; 10 const maxn=105; 11 type 12 ty1=^ty2; 13 ty2=record 14 x:longint; 15 d:int64; 16 next:ty1; 17 end; 18 19 var 20 n,m,i,j,k:longint; 21 d,sum:array[0..maxn,0..maxn] of int64; 22 first:array[0..maxn] of ty1; 23 v:array[0..maxn] of extended; 24 //================= 25 procedure insert(x,y:longint; d:int64); inline; 26 var 27 p:ty1; 28 begin 29 new(p); 30 p^.x:=y; 31 p^.d:=d; 32 p^.next:=first[x]; 33 first[x]:=p; 34 end; 35 //================= 36 procedure find(x,fa:int64); 37 var 38 i:longint; 39 p:ty1; 40 begin 41 inc(sum[fa,x]); 42 p:=first[x]; 43 while p<>nil do 44 begin 45 if (p^.x<>fa)and(d[fa,p^.x]=d[fa,x]+p^.d) then find(p^.x,fa); 46 p:=p^.next; 47 end; 48 end; 49 //================= 50 begin 51 assign(input,'network.in'); reset(input); 52 assign(output,'network.out'); rewrite(output); 53 read(n,m); 54 fillchar(d,sizeof(d),$7); 55 for i:=1 to m do 56 begin 57 read(j,k); 58 read(d[j,k]); d[k,j]:=d[j,k]; 59 insert(j,k,d[j,k]); insert(k,j,d[k,j]); 60 end; 61 for i:=1 to n do d[i,i]:=0; 62 for k:=1 to n do 63 for i:=1 to n do 64 if i<>k then 65 for j:=1 to n do 66 if (j<>i)and(j<>k)and(d[i,k]+d[k,j]<d[i,j]) then 67 d[i,j]:=d[i,k]+d[k,j]; 68 for i:=1 to n do find(i,i); 69 for i:=1 to n do 70 for j:=1 to n do 71 if i<>j then 72 for k:=1 to n do 73 if (k<>i)and(k<>j)and(d[i,k]+d[k,j]=d[i,j]) then 74 v[k]:=v[k]+sum[i,k]*sum[k,j]/sum[i,j]; 75 for i:=1 to n do writeln(v[i]:0:3); 76 close(input); close(output); 77 end.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 (* 2 Problem: NOI2007 社交网络 3 Author: chenyang 4 Time: 2012.5.24 4:41 pm 5 State: 100分 6 Memo: 统计最短路条数 7 *) 8 program network; 9 const maxn=105; 10 var 11 n,m,i,j,k:longint; 12 d,sum:array[0..maxn,0..maxn] of int64; 13 v:array[0..maxn] of extended; 14 //================= 15 begin 16 assign(input,'network.in'); reset(input); 17 assign(output,'network.out'); rewrite(output); 18 read(n,m); 19 fillchar(d,sizeof(d),$7); 20 for i:=1 to m do 21 begin 22 read(j,k); 23 read(d[j,k]); d[k,j]:=d[j,k]; 24 inc(sum[j,k]); inc(sum[k,j]); 25 end; 26 for i:=1 to n do d[i,i]:=0; 27 for k:=1 to n do 28 for i:=1 to n do 29 if i<>k then 30 for j:=1 to n do 31 if (j<>i)and(j<>k)and(d[i,k]+d[k,j]<d[i,j]) then 32 begin 33 d[i,j]:=d[i,k]+d[k,j]; 34 sum[i,j]:=sum[i,k]*sum[k,j]; 35 end else 36 if (j<>i)and(j<>k)and(d[i,k]+d[k,j]=d[i,j]) then 37 inc(sum[i,j],sum[i,k]*sum[k,j]); 38 for i:=1 to n do 39 for j:=1 to n do 40 if i<>j then 41 for k:=1 to n do 42 if (k<>i)and(k<>j)and(d[i,k]+d[k,j]=d[i,j]) then 43 v[k]:=v[k]+sum[i,k]*sum[k,j]/sum[i,j]; 44 for i:=1 to n do writeln(v[i]:0:3); 45 close(input); close(output); 46 end.