[Théorie des graphes] C_calculation_social network (Floyd compte le nombre de chemins les plus courts)

1. Titre Description

Dans la recherche des réseaux sociaux, nous utilisons souvent le concept de théorie des graphes pour expliquer certains phénomènes sociaux.

Regardons un tel problème.

Il n'y a pas de personnes dans un cercle social et il existe différents degrés de relations entre les personnes.

Nous mappons ce réseau de relations à un graphe non orienté de n nœuds. Si deux personnes différentes se connaissent, connectez un bord non orienté entre leurs nœuds correspondants et attachez un poids positif. Plus c et c sont petits, plus la relation entre deux personnes est étroite.

Nous pouvons utiliser la longueur la plus courte entre les nœuds correspondants pour mesurer la proximité de la relation entre les deux personnes s et t. Notez que les autres nœuds sur le chemin le plus court offrent une certaine commodité pour la connexion entre s et t, c'est-à-dire ces nœuds Le point a un certain degré d'importance pour la connexion entre s et t.

Nous pouvons mesurer l'importance d'un nœud dans un réseau social en comptant le nombre de chemins les plus courts à travers un nœud v.

Considérez qu'il peut y avoir plusieurs chemins les plus courts entre deux nœuds A et B.

Nous modifions la définition du niveau d'importance comme suit: Soit Cs, t le nombre de chemins les plus courts différents de s à t, et Cs, t (v) le nombre des chemins les plus courts de s à t après v;

Il est défini
Insérez la description de l'image ici
comme l'importance du nœud v dans les réseaux sociaux.

Afin de donner un sens à I (v) et Cs, t (v), nous stipulons que les réseaux sociaux à traiter sont tous des graphes non dirigés connectés, c'est-à-dire qu'il existe un chemin le plus court de longueur finie entre deux nœuds.

Maintenant, étant donné un tel graphique non orienté pondéré décrivant les réseaux sociaux, veuillez découvrir l'importance de chaque nœud.

Format d'entrée

La première ligne de l'entrée a deux entiers n et m, qui représentent le nombre de nœuds et de bords non orientés dans le réseau social.

Dans le graphe non orienté, nous numérotons tous les nœuds de 1 à n.

Dans les m lignes suivantes, chaque ligne utilise trois entiers a, b et c pour décrire un bord non orienté reliant les nœuds a et b avec un poids de c.

Notez qu'il y a au plus un bord non orienté connecté entre deux nœuds et qu'aucune auto-boucle n'apparaîtra dans le graphique non orienté (c'est-à-dire qu'il n'y a aucun bord non orienté dont les deux extrémités sont le même nœud).

Dans toutes les données, il est garanti que le graphe non orienté donné est connecté et que le nombre de chemins les plus courts entre deux nœuds ne dépasse pas 1010.

Format de sortie

La sortie comprend n lignes, un nombre réel par ligne, précise à 3 décimales près.
Le nombre réel sur la ligne i indique l'importance du nœud i dans le réseau social.

Plage de données
n≤100, m≤4500, 1≤c≤1000

输入样例:
4 4
1 2 1
2 3 1
3 4 1
4 1 1
输出样例:
1.000
1.000
1.000
1.000

Deuxièmement, la solution

Méthode 1: Floyd

  • Quand d[i][j] > d[i][k] + d[k][j]nous pensons de i à j ne passe pas par le nombre le plus court de k est la plus courte et après plusieurs morceaux du même k.
  • Quand d[i][j] = d[i][k] + d[k][j]nous pensons de i à j ne passe pas par le nombre le plus court de k devrait être ajouté après plusieurs k bande la plus courte.

Q&R:

  • Q1: Pourquoi le dernier grand échantillon a-t-il obtenu la réponse WA?
    A1: Le nombre de chemins les plus courts ne dépasse pas 1 0 dix 10 ^ {10} , c'est-à-dire que s'il y a une multiplication ×, le résultat du calcul deviendra très grand. Si vous définissez INF comme 0x3f, il est facile de dépasser, donc lorsque la multiplication × apparaît, vous devez ouvrir les constantes qui sont généralement définies.
import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
	static int V, E;
	static double[][] d,c;
	static int INF = (int)1e20;	//注
	static int maxv = 100 + 50, maxe = 4500 + 50;
	static void floyd() {
		for (int k = 1; k <= V; k++)
		for (int i = 1; i <= V; i++)
		for (int j = 1; j <= V; j++) {
			if(k == i || i == j || k == j)
				continue;
			if (d[i][j] > d[i][k] + d[k][j]) {
				d[i][j] = d[i][k] + d[k][j];
				c[i][j] = c[i][k] * c[k][j];
			} else if (d[i][j] == d[i][k] + d[k][j]) {
				c[i][j] += c[i][k] * c[k][j];
			}
		}
	}
    public static void main(String[] args) throws IOException {  
        Scanner sc = new Scanner(new BufferedInputStream(System.in));
		V = sc.nextInt();
		E = sc.nextInt();
        c = new double[maxv][maxv];		
        d = new double[maxv][maxv];	
		
        for (int i = 1; i <= V; i++)
		for (int j = 1; j <= V; j++) {
		    if (i != j) {
		        d[i][j] = INF;
		    }
		}
		
		for (int i = 0; i < E; i++) {
			int a = sc.nextInt();
			int b = sc.nextInt();
			double w = sc.nextDouble();
			d[a][b] = d[b][a] = w;
			c[a][b] = c[b][a] = 1;
		}
		floyd();
		double[] imp = new double[V+1];
		for (int i = 1; i <= V; i++)
		for (int j = 1; j <= V; j++)
		for (int v = 1; v <= V; v++) {
		    if (i == j || j == v || i == v)
				continue;
		    if (d[i][j] == d[i][v] + d[v][j])
				imp[v] += (c[i][v]*c[v][j]) / c[i][j];
		}
	    for (int i = 1; i <= V; i++) {
			System.out.printf("%.3f\n", imp[i]);
		}
    }
}

Analyse de complexité

  • Complexité temporelle: Le ( V 3 ) O (V ^ 3)
  • Complexité de l'espace: O ( V 3 ) O (V ^ 3)
Publié 714 articles originaux · loué 199 · 50 000+ vues

Je suppose que tu aimes

Origine blog.csdn.net/qq_43539599/article/details/105590700
conseillé
Classement