【圖論】B_LQ_任意兩點的路徑總和(floyd / dfs + 策略)

一、Problem

在這裏插入圖片描述
輸入

第一行,一個數n。

接下來 n−1 行,每行輸入三個數 u,v,w.

輸出

輸出距離和。

10
1 2 3
1 3 4
1 4 5
2 5 8
3 6 7
6 7 10
7 8 12
8 9 13
3 10 2

966

二、Solution

方法一:floyd

留下 MLE 的淚水…😂

import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
	static class Solution {
		int N, INF = 0x3f3f3f3f;
		int[][] dp;
		void floyd() {
			for (int k = 1; k <= N; k++)
			for (int i = 1; i <= N; i++)
			for (int j = 1; j <= N; j++) {
				dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k][j]);
			}
		}
		void init() {
			Scanner sc = new Scanner(new BufferedInputStream(System.in));
			N = sc.nextInt();
			dp = new int[N+1][N+1];
			for (int i = 1; i <= N; i++)
			for (int j = 1; j <= N; j++) {
				dp[i][j] = INF;
			}
			for (int i = 0; i < N-1; i++) {
				int a = sc.nextInt(), b = sc.nextInt(), c = sc.nextInt();
				dp[a][b] = c;
				dp[b][a] = c;
			}
			floyd();
			long sum = 0;
			for (int i = 1; i <= N; i++)
			for (int j = i+1; j <= N; j++) {
				sum += dp[i][j];
			}
			System.out.println(sum);
		}
	}
    public static void main(String[] args) throws IOException {  
        Solution s = new Solution();
		s.init();
    }
}

複雜度分析

  • 時間複雜度:O(n3)O(n^3)
  • 空間複雜度:O(n3)O(n^3)

方法二:策略 dfs

  • 對於一個圖中的某條邊 e,在 e 的左右任意挑選兩個點 u、v 的連線一定經過邊 e
  • e 被經過的次數也就是 e 的左邊的點數 ll ×× 右邊的點數 rr
  • 邊 e 貢獻的總權值就是 l×r×w[e]l × r × w[e]

未知錯誤:原來是 g[a] g[b] 初始化的時候…唉

import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
	static class Solution {
		int N;
		int[] sz;
		List<Pair> g[];
		long sum;
		
		void dfs(int v, int f) {
			sz[v] = 1;			//當前結點的結點數
			for (int i = 0; i < g[v].size(); i++) {
				int to = g[v].get(i).to, w = g[v].get(i).w;
				if (to == f)
					continue;
				dfs(to, v);
				sum += (sz[to] * (N-sz[to])) * w;
				sz[v] += sz[to];
			}
		}
		void init() {
			Scanner sc = new Scanner(new BufferedInputStream(System.in));
			N = sc.nextInt();
			sz = new int[N+1];
			g = new ArrayList[2*N + 5];
			for (int i = 0; i < N-1; i++) {
				int a = sc.nextInt(), b = sc.nextInt(), c = sc.nextInt();
				g[a] = new ArrayList<>();
				g[b] = new ArrayList<>();
				g[a].add(new Pair(b, c));
				g[b].add(new Pair(a, c));
			}
			dfs(1, -1);
			System.out.println(sum);
		}
		class Pair {
			int to, w;
			Pair(int to, int w) {this.to = to;this.w = w;}
		}
	}
    public static void main(String[] args) throws IOException {  
        Solution s = new Solution();
		s.init();
    }
}

又來一波 RE,留下無情的淚水 😂:我猜這波一定是 long 型溢出了…,怎麼辦?還有別的辦法嗎?求仙人指路!

import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
	static class Solution {
		int N, MAXN = 100000 * 2 + 5;
		int[] sz;
		List<Pair> g[];
		long sum;
		void dfs(int v, int f) {
			sz[v] = 1;			//當前結點的結點數
			for (int i = 0; i < g[v].size(); i++) {
				int to = g[v].get(i).to, w = g[v].get(i).w;
				if (to == f)
					continue;
				dfs(to, v);
				sum += 1l * sz[to] * (N-sz[to]) * w;
				sz[v] += sz[to];
			}
		}
		void init() {
			Scanner sc = new Scanner(new BufferedInputStream(System.in));
			N = sc.nextInt();
			sz = new int[N+1];
			g = new ArrayList[MAXN];
			for (int i = 0; i < g.length; i++) {
		    	g[i] = new ArrayList<>();
			} 
			for (int i = 0; i < N-1; i++) {
				int a = sc.nextInt(), b = sc.nextInt(), c = sc.nextInt();
				g[a].add(new Pair(b, c));
				g[b].add(new Pair(a, c));
			}
			dfs(1, -1);
			System.out.println(sum);
		}
		class Pair {
			int to, w;
			Pair(int to, int w) {this.to = to;this.w = w;}
		}
	}
    public static void main(String[] args) throws IOException {  
        Solution s = new Solution();
		s.init();
    }
}

複雜度分析

  • 時間複雜度:O(V+E)O(V+E)
  • 空間複雜度:O(V+E)O(V+E)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章