在社交网络中,个人或单位(结点)之间通过某些关系(边)联系起来。他们受到这些关系的影响,这种影响可以理解为网络中相互连接的结点之间蔓延的一种相互作用,可以增强也可以减弱。而结点根据其所处的位置不同,其在网络中体现的重要性也不尽相同。
“紧密度中心性”是用来衡量一个结点到达其它结点的“快慢”的指标,即一个有较高中心性的结点比有较低中心性的结点能够更快地(平均意义下)到达网络中的其它结点,因而在该网络的传播过程中有更重要的价值。在有N个结点的网络中,结点vi的“紧密度中心性”Cc(vi)数学上定义为vi到其余所有结点vj (j=i) 的最短距离d(vi,vj)的平均值的倒数:
对于非连通图,所有结点的紧密度中心性都是0。
给定一个无权的无向图以及其中的一组结点,计算这组结点中每个结点的紧密度中心性。
输入格式:
输入第一行给出两个正整数N和M,其中N(≤104)是图中结点个数,顺便假设结点从1到N编号;M(≤105)是边的条数。随后的M行中,每行给出一条边的信息,即该边连接的两个结点编号,中间用空格分隔。最后一行给出需要计算紧密度中心性的这组结点的个数K(≤100)以及K个结点编号,用空格分隔。
输出格式:
按照Cc(i)=x.xx
的格式输出K个给定结点的紧密度中心性,每个输出占一行,结果保留到小数点后2位。
一看就是正经的Dijkstra算法,只是它的简化版,因为题目的意思直接就是给你权值默认成1了,省去了一些细节,再有,我想吐槽一下这个内存问题啊,我就多开了一个二维数组就内存超限了,气得我直接把Dijkstra算法在main函数里实现了,省去了一个二维数组就能过了,还有就是判断回路问题,个人的方法就是在寻找最小值的时候,如果没有寻找到(初始时设置的值没有被修改就退出这样没有找全n-1个点,就判断不是回路了,有很多方法就不多赘述了),还有一定不要被那么长的题干给吓住了(好歹是经历过新高考信息题的人,哈哈~~),其实前面的都是废话,直到那个公式附近才是真正的题干,啧啧~
个人觉得可能还会有更快内存消耗更少的方法,那个以后学会了再说~~~嘻嘻
那话不多说上代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include<vector>
#include <iomanip>
#define maxm 30005
using namespace std;
//int G[10001][10001];
int n,m;
int visited[10001];
int d[10001];
/*
int Dijkstra(int s)
{
memset(visited,0,sizeof(visited));
memset(d,maxm,sizeof(d));
visited[s]=1;
d[s]=0;
for(int i=1;i<=n;i++)
{
if(G[s][i])
d[i]=1;
}
int count=1;
while(count<n)
{
int minidx=0;
int minv=maxm;
for(int i=1;i<=n;i++)
{
if(!visited[i]&&d[i]<minv)
{
minv=d[i];
minidx=i;
}
}
visited[minidx]=1;
if(minv==maxm)
break;
for(int j=1;j<=n;j++)
{
if(!visited[j]&&G[minidx][j]&&d[j]>d[minidx]+G[minidx][j])
d[j]=d[minidx]+G[minidx][j];
}
count++;
}
int sum=0;
if(count!=n)
return sum;
for(int i=1;i<=n;i++)
sum+=d[i];
return sum;
}
*/
int main()
{
cin>>n>>m;
int G[n+1][n+1];
memset(G,0,sizeof(G));
for(int i=0; i<m; i++)
{
int s,d;
cin>>s>>d;
G[s][d]=1;
G[d][s]=1;
}
int k;
cin>>k;
int a[k];
for(int i=0; i<k; i++)
cin>>a[i];
for(int i=0; i<k; i++)
{
int s=a[i];
memset(visited,0,sizeof(visited));
memset(d,maxm,sizeof(d));
visited[s]=1;
d[s]=0;
for(int i=1; i<=n; i++)
{
if(G[s][i])
d[i]=1;
}
int count=1;
while(count<n)
{
int minidx=0;
int minv=maxm;
for(int i=1; i<=n; i++)
{
if(!visited[i]&&d[i]<minv)
{
minv=d[i];
minidx=i;
}
}
visited[minidx]=1;
if(minv==maxm)
break;
for(int j=1; j<=n; j++)
{
if(!visited[j]&&G[minidx][j]&&d[j]>d[minidx]+G[minidx][j])
d[j]=d[minidx]+G[minidx][j];
}
count++;
}
int sum=0;
if(count!=n)
{cout<<"Cc("<<a[i]<<")="<<"0.00"<<endl;continue;}
for(int i=1; i<=n; i++)
sum+=d[i];
double ans=(double)(n-1)/sum;
cout<<fixed<<setprecision(2)<<"Cc("<<a[i]<<")="<<ans<<endl;
}
return 0;
}
/*
9 14
1 2
1 3
1 4
2 3
3 4
4 5
4 6
5 6
5 7
5 8
6 7
6 8
7 8
7 9
3 3 4 9
*/