[グラフ理論] C_calculation_social network(フロイドは最短経路の数を数える)

1.タイトルの説明

ソーシャルネットワークの研究では、グラフ理論の概念を使用していくつかの社会現象を説明することがよくあります。

そのような問題を見てみましょう。

ソーシャルサークルにはn人の人々がいて、人々の間にはさまざまな程度の関係があります。

この関係ネットワークをnノードの無向グラフにマッピングします。2人の異なる人がお互いを知っている場合、対応するノード間に無向エッジを接続し、正の重みを付けます。 cとcが小さいほど、2人の関係はより近くなります。

対応するノード間の最短の長さを使用して、2人のsとtの間の関係の近さを測定できます。最短パス上の他のノードは、sとtの間の接続にいくつかの便宜を提供することに注意してください。つまり、これらのノードポイントは、sとtの間の接続にある程度重要です。

ノードvを通る最短経路の数を数えることにより、ソーシャルネットワークにおけるノードの重要性を測定できます。

2つのノードAとBの間に複数の最短パスがある可能性があることを考慮してください。

重要度レベルの定義を次のように変更します。Cs、tをsからtへの異なる最短パスの数、Cs、t(v)をvの後のsからtへの最短パスの数とします。


ここに画像の説明を挿入
ソーシャルネットワークにおけるノードvの重要性として定義されます。

I(v)とCs、t(v)を意味のあるものにするために、処理されるソーシャルネットワークはすべて接続された無向グラフである、つまり、任意の2つのノード間に有限長の最短経路があると規定します。

ソーシャルネットワークを記述するこのような重み付けされた無向グラフが与えられたら、各ノードの重要性を見つけてください。

入力フォーマット

入力の最初の行には、ソーシャルネットワークのノードと無向エッジの数を表す2つの整数nとmがあります。

無向グラフでは、1からnまでのすべてのノードに番号を付けます。

次のm行では、各行は3つの整数a、b、cを使用して、ノードaとbを接続する無向エッジを重みcで記述しています。

2つのノード間に接続されている無向エッジは最大で1つであり、無向グラフには自己ループが表示されないことに注意してください(つまり、2つの端点が同じノードである無向エッジはありません)。

すべてのデータで、指定された無向グラフが接続され、2つのノード間の最短経路の数が1010を超えないことが保証されています。

出力フォーマット

出力にはn行が含まれ、1行に1つの実数、小数点以下第3位まで正確です。
行iの実数は、ソーシャルネットワークにおけるノードiの重要性を示します。

データ範囲
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

第二に、解決策

方法1:フロイド

  • ときd[i][j] > d[i][k] + d[k][j]、我々はiからjまでのだと思うkの最短数を通過しない最短と同じkのいくつかの部分の後です。
  • ときd[i][j] = d[i][k] + d[k][j]、我々はiからjまでのだと思うkの最短数を通過しないいくつかの最短ストリップkの後に追加する必要があります。

Q&A:

  • Q1:なぜ最後の大きなサンプルがWAと答えたのですか?
    A1:最短経路の数は超えない 1 0 10 10 ^ {10} 、つまり乗算×がある場合、計算結果は非常に大きくなります。INFを0x3fとして定義すると、簡単に超過するため、乗算×が表示されたときに、通常定義されている定数を開く必要があります。
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]);
		}
    }
}

複雑さの分析

  • 時間の複雑さ: V 3 ) O(V ^ 3)
  • スペースの複雑さ: O ( V 3 ) O(V ^ 3)
元の記事714件を公開 賞賛された199件 50,000件以上の表示

おすすめ

転載: blog.csdn.net/qq_43539599/article/details/105590700