1. 程式人生 > >社交網路圖中結點的“重要性“計算(Dijkstra + SPFA + Floyd + 模板)

社交網路圖中結點的“重要性“計算(Dijkstra + SPFA + Floyd + 模板)

題目連結:

題目大意:

求一個點到其他所有點的最短距離和,保證圖連通。

解題過程:

剛開始用 Floyd 水過的,後來用換了幾種方法,不錯的模板題,Floyd 的時候,要用 vector 存邊,否則超記憶體。

題目分析

AC程式碼(Dijkstra + SPFA)

#include<bits/stdc++.h>
using namespace std;

const int MAX = 11234, INF = 0x3f3f3f3f;

vector<int> edges[MAX];
int dist[MAX], book[MAX];

void
spfa(int s) { memset(dist, INF, sizeof(dist)); memset(book, 0, sizeof(book)); queue<int> q; q.push(s); book[s] = 1; dist[s] = 0; while (!q.empty()) { int u = q.front(); for (int i = 0; i < edges[u].size(); i++) { int v = edges[u][i]; if
(dist[v] > dist[u] + 1) { dist[v] = dist[u] + 1; if (!book[v]) { q.push(v); book[v] = 1; } } } q.pop(); book[u] = 0; } } void dijkstra(int s) { memset(dist, INF, sizeof
(dist)); priority_queue<pair<int, int> > q; dist[s] = 0; q.push(make_pair(-dist[s], s)); while (!q.empty()) { int u = q.top().second; q.pop(); for (int i = 0; i < edges[u].size(); i++) { int v = edges[u][i]; if (dist[v] > dist[u] + 1) { dist[v] = dist[u] + 1; q.push(make_pair(-dist[v], v)); } } } } int main() { int n, m; scanf("%d %d", &n, &m); while (m--) { int u, v; scanf("%d %d", &u, &v); edges[u].push_back(v); edges[v].push_back(u); } int k; scanf("%d", &k); while (k--) { int s; scanf("%d", &s); dijkstra(s); int sum = 0; for (int i = 1; i <= n; i++) { if (i == s) continue; sum += dist[i]; } printf("Cc(%d)=%.2f\n", s, (n-1.0)/sum); } }

AC程式碼(Floyd):

#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f, MAX = 10001;

int main()
{
    vector<int>edge[MAX];
    int n, m;
    scanf("%d %d", &n, &m);

    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= n; j++) {
            edge[i].push_back(INF);
        }
    }

    for (int i = 1; i <= n; i++) {
        edge[i][i] = 0;
    }

    for (int i = 0; i < m; i++) {
        int u, v;
        scanf("%d %d", &u, &v);
        edge[u][v] = edge[v][u] = 1;
    }

    for (int k = 1; k <= n; k++) {
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (edge[i][j] > edge[i][k] + edge[k][j])
                    edge[i][j] = edge[i][k] + edge[k][j];
            }
        }
    }

    int k;
    scanf("%d", &k);
    while (k--) {
        int c;
        scanf("%d", &c);
        double sum = 0;
        for (int i = 1; i <= n; i++) {
            if (i == c)
                continue;
            sum += edge[c][i];
        }
        printf("Cc(%d)=%.2f\n", c, (n-1)/sum);
    }
}