原题链接:蓝桥杯历届试题-城市建设
解题思路:
将河道看成一个顶点
注意事项:
只要权值是负的 ,都要加入到最小生成树的边集中,生成数的边集数要加1;如果连接河道的边集只有一条边,那就把结果减去这条边的权值。
参考代码:
import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Scanner; import java.util.Set; public class Main { static List<Edge> edgeList = new ArrayList<Edge>(); static Set<Edge> T = new HashSet<>(); static int n; static Map<Integer, UnionFind.UFNode> pntAndNode = new HashMap<Integer, UnionFind.UFNode>(); public static void main(String[] args) { Scanner sc = new Scanner(System.in); n = sc.nextInt(); int m = sc.nextInt(); while(m-- > 0 ){ edgeList.add(new Edge(sc.nextInt(),sc.nextInt(),sc.nextInt())); } for(int i = 1; i <= n; i++){ int dis = sc.nextInt(); if(dis != -1){ edgeList.add(new Edge(0,i,dis)); } } buildMap(); Set<Edge> t = getT(); int res = 0; int count = 0;//记录河道的边数 int cou = 0;//河道边的权值 for (Edge edge : t) { if(edge.getEnd()==0){ count++; cou = edge.getDistance(); } if(edge.getStart() == 0){ count++; cou = edge.getDistance(); } res += edge.distance; } if(count == 1){//如果河道只有一条边 res -= cou;//结果就减去这条边的权值 } System.out.println(res); } private static Set<Edge> getT() { buildMis(); return T; } private static void buildMis() { Collections.sort(edgeList); for (Edge e: edgeList) { if(!ok(e)){ if(e.distance < 0){ T.add(e); n +=1; } continue; } T.add(e); if(T.size() == n){ return ; } } } private static boolean ok(Edge e) { UnionFind.UFNode x = pntAndNode.get(e.getStart()); UnionFind.UFNode y = pntAndNode.get(e.getEnd()); if(UnionFind.find(x) != UnionFind.find(y)){ UnionFind.UnionNode(x, y); return true; } return false; } private static void buildMap() { for (Edge edge : edgeList) { pntAndNode.put(edge.start, new UnionFind.UFNode()); pntAndNode.put(edge.end, new UnionFind.UFNode()); } } } class UnionFind{ // 并查集 public static UFNode find(UFNode x){ UFNode p = x; Set<UFNode> n = new HashSet<>(); while(p.parent != null){ n.add(p); p = p.parent; } for (UFNode node : n) { node.parent = p; } return p; } public static void UnionNode(UFNode x,UFNode y){ UnionFind.find(y).parent = UnionFind.find(x); } public static class UFNode{ public UFNode parent; @Override public String toString() { return "UFNode [parent=" + parent + "]"; } } } class Edge implements Comparable<Edge>{ public Integer start; public Integer end; public Integer distance; public Edge(Integer start, Integer end, Integer distance) { super(); this.start = start; this.end = end; this.distance = distance; } public Integer getStart() { return start; } public Integer getEnd() { return end; } public Integer getDistance() { return distance; } @Override public String toString() { return "Edge [start=" + start + ", end=" + end + ", distance=" + distance + "]"; } @Override public int compareTo(Edge o) { // TODO Auto-generated method stub return this.distance - o.distance; } }
0.0分
1 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复