tsinsen A1364. 社交网络结构洞

试题来源
  清华大学2012年信息学优秀高中学子夏令营
问题描述
  近日,社交网络研究的鼻祖Jon Kleinberg教授在清华大学给同学们带来了一个关于社交网络结构洞(Structural Hole)的主题演讲。对社交网络有着浓厚兴趣的小W也旁听了这次演讲。在演讲中Jon Kleinberg教授讲到社交网络结构洞是描述一个人在一个社交网络中重要程度的一个指标,那么如何定量地分析每一个人在社交网络的重要程度呢?
  小W阅读很多参考文献,发现有一种通过计算社会关系跨度的方法。


  【定义】社交网络用表示一个社交网络,其中是网络中人的集合,是人与人之间的关系集合。
  【定义】社交网络距离两个人的社交网络距离之间的最短距离。
  【定义】社会关系跨度用表示,是在社交网络中去掉所有与相关的边(即边的一个端点为)之后之间的最短距离。
  那么描述每一个人的结构洞值表示其所有邻居节点之间社会关系跨度与社交网络距离差值的和。

  (结构洞值的定义)


  其中表示的邻居节点集合。
  由于社交网络中人的数量十分庞大,计算每个人的结构洞值也变得十分困难。小W想请你帮助设计出一种好的计算方法,求出社交网络中所有人的结构洞值。
输入格式
  输入的第一行包含两个整数n,m,表示社交网络中人的数量(人从1到n编号)和关系的数量。
  接下来m行描述人们的关系情况,其中第i行包含两个整数ai和bi, 1<=ai,bi<=n,表示ai和bi两个人之间在社交网络中有直接关系。
输出格式
  输出一共n行,每行一个整数,表示每个人在社交网络中的结构洞值。
样例输入
5 7
2 4
5 4
3 2
3 4
3 1
5 3
5 1
样例输出
0
0
1
0
0
对样例的说明
数据规模和约定
  所有测试数据的范围和特点如下表所示。
 
 
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define N 4100
#define M 101000
struct P{
   int x,y;
}a[M];
int nn;
void add(int x,int y){
   nn++;
   a[nn].x=x;
   a[nn].y=y;
}
int n,m;
int qu[N],qu2[N],he,bo;
int f[N][2],d[N][2];
int cc[2100][2200];
int op[N];
int p[N],q[N];
int v[M];
void bfs(int x){
    for(int i=1;i<=n;i++){
       f[i][1]=-1,f[i][0]=-1;    
    }
    he=0,bo=1;
    int y,z;
    f[x][1]=0;
    f[x][0]=0;
    for(int i=p[x];i<=q[x];i++){
        f[v[i]][0]=v[i];
        d[v[i]][0]=1;
        qu[++he]=v[i];
        qu2[he]=0;
    }
    while(he>=bo){    
         y=qu[bo];
         z=qu2[bo++];
         for(int i=p[y];i<=q[y];i++){
            if(f[v[i]][0]==-1){
                f[v[i]][0]=f[y][z];
                d[v[i]][0]=d[y][z]+1;
                qu[++he]=v[i];
                qu2[he]=0;        
            }else{
                if(!cc[v[i]][x]&&f[v[i]][1]==-1&&f[v[i]][0]!=f[y][z]){
                    f[v[i]][1]=f[y][z];
                    d[v[i]][1]=d[y][z]+1;
                    qu[++he]=v[i];
                    qu2[he]=1;        
                }    
            }
        }
    }
    for(int i=p[x];i<=q[x];i++){
       for(int j=p[v[i]];j<=q[v[i]];j++){
            if(v[j]==x)continue;
            if(f[v[j]][0]==v[i]){
                op[v[i]]+=(d[v[j]][1]-d[v[j]][0]);    
            }    
        }    
    }
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
       int a,b;
       scanf("%d%d",&a,&b);
       add(a,b);
       add(b,a);    
       cc[a][b]=1;
       cc[b][a]=1;
    }
    for(int i=1;i<=nn;i++){
        q[a[i].x]++;    
    }
    for(int i=1;i<=n;i++)q[i]+=q[i-1],p[i]=q[i];
    for(int i=1;i<=nn;i++){
       v[p[a[i].x]--]=a[i].y;    
    }
    for(int i=1;i<=n;i++)p[i]++;
    for(int i=1;i<=n;i++)bfs(i);
    for(int i=1;i<=n;i++){
       printf("%d\n",op[i]/2);    
    }
    
}

 

posted @ 2014-06-11 22:34  wangyucheng  阅读(2425)  评论(2编辑  收藏  举报