本文主要是介绍P2330 [SCOI2005] 繁忙的都市,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Problem: P2330 [SCOI2005] 繁忙的都市
文章目录
- 思路
- 解题方法
- 复杂度
- Code
思路
这是一道最小生成树(Minimum Spanning Tree)的问题。我们可以使用Kruskal算法来解决。
解题方法
首先,我们需要将所有的道路按照分值从小到大进行排序。然后,我们从分值最小的道路开始,依次判断这条道路的两个交叉路口是否已经连通。如果两个交叉路口不连通,我们就将它们连通,并将这条道路的分值作为当前的最大分值。
我们继续判断下一条分值较小的道路,直到所有的交叉路口都连通为止。最后,我们得到的最小生成树就是我们需要修建的道路,而最大分值就是我们的答案。
复杂度
时间复杂度:
O ( m l o g m + n 2 ) O(mlogm + n^2) O(mlogm+n2),其中m是道路的数量,n是交叉路口的数量。
空间复杂度:
O ( n ) O(n) O(n),用于存储并查集的父节点。
Code
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;public class Main {static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));static StreamTokenizer sr = new StreamTokenizer(in);static int MAXN = 310;static int MAXM = 8010;static int n, m;static int[][] edges = new int[MAXM][3];static int[] father = new int[MAXN];static void build(int n) {for (int i = 1; i <= n; i++) {father[i] = i;}}static int find(int i) {if (i != father[i]) {father[i] = find(father[i]);}return father[i];}static boolean union(int x, int y) {int fx = find(x);int fy = find(y);if (fx != fy) {father[fx] = fy;return true;}return false;}public static void main(String[] args) throws IOException {n = nextInt();m = nextInt();build(n);for (int i = 0; i < m; i++) {edges[i][0] = nextInt();edges[i][1] = nextInt();edges[i][2] = nextInt();}Arrays.sort(edges, 0, m, (a, b) -> a[2] - b[2]);int ans = 0;int edgeCnt = 0;for (int[] edge : edges) {if (union(edge[0], edge[1])) {ans = Math.max(ans, edge[2]);edgeCnt++;}if(n - 1 == edgeCnt) {break;}}out.println(n - 1 + " " + ans);out.flush();}static int nextInt() throws IOException {sr.nextToken();return (int) sr.nval;}}
这篇关于P2330 [SCOI2005] 繁忙的都市的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!