PTA 7-12(圖) 社交網絡圖中結點的「重要性」計算 最短路

7-12(圖) 社交網絡圖中結點的「重要性」計算 (30 分)

在社交網絡中,我的或單位(結點)之間經過某些關係(邊)聯繫起來。他們受到這些關係的影響,這種影響能夠理解爲網絡中相互鏈接的結點之間蔓延的一種相互做用,能夠加強也能夠減弱。而結點根據其所處的位置不一樣,其在網絡中體現的重要性也不盡相同。html

「緊密度中心性」是用來衡量一個結點到達其它結點的「快慢」的指標,即一個有較高中心性的結點比有較低中心性的結點可以更快地(平均意義下)到達網絡中的其它結點,於是在該網絡的傳播過程當中有更重要的價值。在有N個結點的網絡中,結點vi​​的「緊密度中心性」Cc(vi​​)數學上定義爲vi​​到其他全部結點vj​​ (ji) 的最短距離d(vi​​,vj​​)的平均值的倒數:ios

對於非連通圖,全部結點的緊密度中心性都是0。算法

給定一個無權的無向圖以及其中的一組結點,計算這組結點中每一個結點的緊密度中心性。網絡

輸入格式:

輸入第一行給出兩個正整數N和M,其中N(104​​)是圖中結點個數,順便假設結點從1到N編號;M(105​​)是邊的條數。隨後的M行中,每行給出一條邊的信息,即該邊鏈接的兩個結點編號,中間用空格分隔。最後一行給出須要計算緊密度中心性的這組結點的個數K(100)以及K個結點編號,用空格分隔。spa

輸出格式:

按照Cc(i)=x.xx的格式輸出K個給定結點的緊密度中心性,每一個輸出佔一行,結果保留到小數點後2位。code

輸入樣例:

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算法裸過,讀入的時候判一下是否是連通圖htm

AC代碼:blog

#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;
}
相關文章
相關標籤/搜索