PTA 7-12(图) 社交网络图中结点的“重要性”计算 最短路

7-12(图) 社交网络图中结点的“重要性”计算 (30 分)

在社交网络中,个人或单位(结点)之间通过某些关系(边)联系起来。他们受到这些关系的影响,这种影响可以理解为网络中相互连接的结点之间蔓延的一种相互作用,可以增强也可以减弱。而结点根据其所处的位置不同,其在网络中体现的重要性也不尽相同。

“紧密度中心性”是用来衡量一个结点到达其它结点的“快慢”的指标,即一个有较高中心性的结点比有较低中心性的结点能够更快地(平均意义下)到达网络中的其它结点,因而在该网络的传播过程中有更重要的价值。在有N个结点的网络中,结点vi​​的“紧密度中心性”Cc(vi​​)数学上定义为vi​​到其余所有结点vj​​ (ji) 的最短距离d(vi​​,vj​​)的平均值的倒数:

对于非连通图,所有结点的紧密度中心性都是0。

给定一个无权的无向图以及其中的一组结点,计算这组结点中每个结点的紧密度中心性。

输入格式:

输入第一行给出两个正整数N和M,其中N(104​​)是图中结点个数,顺便假设结点从1到N编号;M(105​​)是边的条数。随后的M行中,每行给出一条边的信息,即该边连接的两个结点编号,中间用空格分隔。最后一行给出需要计算紧密度中心性的这组结点的个数K(100)以及K个结点编号,用空格分隔。

输出格式:

按照Cc(i)=x.xx的格式输出K个给定结点的紧密度中心性,每个输出占一行,结果保留到小数点后2位。

输入样例:

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

输出样例:

Cc(3)=0.47
Cc(4)=0.62
Cc(9)=0.35

思路:简单的稀疏图最短路问题,甚至不需要保存边权(均为一),dijkstra算法裸过,读入的时候判一下是不是连通图

AC代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <cstdio>
#include <malloc.h>

#define INF 0x3f3f3f3f
#define FRER() freopen("in.txt", "r", stdin)
#define FREW() freopen("out.txt", "w", stdout)

using namespace std;

const int maxn = 10000 + 5;

vector<int> g[maxn];

int n, m, s, u, v, vis[maxn], dis[maxn];

typedef pair<int, int> P;

void dijkstra() {
    memset(vis, 0, sizeof(vis));
    memset(dis, INF, sizeof(dis));
    priority_queue<P, vector<P>, greater<P> > q;
    dis[s] = 0;
    q.push(make_pair(0, s));
    P tmp;
    while(!q.empty()) {
        tmp = q.top(); q.pop();
        if(vis[tmp.second]) continue;
        vis[tmp.second] = 1;
        for(int i = 0; i < g[tmp.second].size(); ++i) {
            if(tmp.first + 1 < dis[g[tmp.second][i]]) {
                dis[g[tmp.second][i]] = tmp.first + 1;
                q.push(make_pair(dis[g[tmp.second][i]], g[tmp.second][i]));
            }
        }
    }
}

double cal() {
    double ans = 0;
    for(int i = 1; i <= n; ++i) 
            ans += (double)dis[i];
    return (n - 1) / ans;
}

int main()
{
    scanf("%d %d", &n, &m);
    int num = 0;
    while(m--) {
        scanf("%d %d", &u, &v);
        g[u].push_back(v);
        g[v].push_back(u);
        if(!vis[u]) vis[u] = 1, ++num;
        if(!vis[v]) vis[v] = 1, ++num;
    }
    
    bool ok = !(num == n);
    scanf("%d", &m);
    while(m--) {
        scanf("%d", &s);
        if(ok) printf("Cc(%d)=0.00\n", s);
        else {
            dijkstra();
            printf("Cc(%d)=%.2lf\n", s, cal());
        }
    }
    return 0;
}
 

猜你喜欢

转载自www.cnblogs.com/fan-jiaming/p/10105737.html