CCF-CSP 交通规划 JAVA 2016-09-04 100分
2017-10-08 19:53
429 查看
参考资料:
dijkstra和Floyd算法思想:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html
C++代码版:http://blog.csdn.net/moilk_nepho/article/details/52950546
JAVA优先队列使用:http://www.importnew.com/6932.html
JAVA类中类问题:https://www.baidu.com/s?ie=UTF-8&wd=java%20%E7%B1%BB%E4%B8%AD%E7%B1%BB
Comparable 和Comparator 详解及区别:http://blog.csdn.net/sinat_34979528/article/details/54407678
cannot be cast to java.lang.Comparable解决办法:http://blog.sina.com.cn/s/blog_944bf8ef0101jczp.html
解题思路:
题目要求 “所有城市到首都的最短距离都和原来一样长” 可见这是一个单源最短路径问题。
且要求出最少要改造多少铁路,即要求:所有符合最短路径条件的边,用这样的边,连通所有点所需要的最小花费。
样例:
dijkstra和Floyd算法思想:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html
C++代码版:http://blog.csdn.net/moilk_nepho/article/details/52950546
JAVA优先队列使用:http://www.importnew.com/6932.html
JAVA类中类问题:https://www.baidu.com/s?ie=UTF-8&wd=java%20%E7%B1%BB%E4%B8%AD%E7%B1%BB
Comparable 和Comparator 详解及区别:http://blog.csdn.net/sinat_34979528/article/details/54407678
cannot be cast to java.lang.Comparable解决办法:http://blog.sina.com.cn/s/blog_944bf8ef0101jczp.html
解题思路:
题目要求 “所有城市到首都的最短距离都和原来一样长” 可见这是一个单源最短路径问题。
且要求出最少要改造多少铁路,即要求:所有符合最短路径条件的边,用这样的边,连通所有点所需要的最小花费。
样例:
package csp2016_09_4; /** * 收获: * 到底是对象运算快还是普通运算快 在这里——用静态还是动态好? * djs算法和延伸 * 常见图论算法的写法 * 类中类的问题 * final static * List的使用及List[]时要注意每项都实例化 * 优先队列PriorityQueue * Comparator和Comparable区别和使用细节 * * */ import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.PriorityQueue; import java.util.Queue; import java.util.Scanner; class Node implements Comparable<Node>{ //出发点到V点的距离为cost public int v=0,cost=0; Node(){} Node(int v,int cost){ this.v = v; this.cost = cost; } public int compare(Node o1, Node o2) { // return ((Node)o1).cost-((Node)o2).cost; //Comparator<默认Object> return o1.cost-o2.cost; } @Override public int compareTo(Node o) { return this.cost-o.cost; } // public static Comparator<Node> costComparator = new Comparator<Node>(){ // public int compare(Node c1, Node c2) { // return (c1.cost - c2.cost); // } // }; } class Edge{ // 该点到点V的距离为W int v,w=0; Edge(int v,int w){ this.v = v; this.w = w; } // int s=0,e=0,w=0; // Edge(int s,int e,int w){ // this.s = s; // this.e = e; // this.w = w; // } } public class Main { Main(){ for (int i = 0; i < G.length; i++) { G[i] = new ArrayList(); } } final static int MAXN = 10010; final static int MAXINT = 0xfffffff; // ArrayList G[] = new ArrayList[MAXN]; List <Edge>G[] = new ArrayList[MAXN]; boolean vis[] = new boolean[MAXN]; //每个点只应该被访问一次 int dis[] =new int[MAXN]; //出发点到某点的距离 // int prev[] = new int[MAXN]; //传统djs,求前驱顶点,得最短路径 int costo[] = new int[MAXN]; //当满足最短路径条件下,要接通该点所需要的最小花费。 int n,m; public static void main(String[] args) { Main a = new Main(); Scanner sc = new Scanner(System.in); a.n = sc.nextInt(); a.m = sc.nextInt(); // int[][] A = new int[m][3]; // for (int i = 0; i < A.length; i++) { // for (int j = 0; j < A[i].length; j++) { // A[i][j] = sc.nextInt(); // } // } // Main.run(); int s,e,w; for (int i = 0; i < a.m; i++) { s = sc.nextInt(); e = sc.nextInt(); w = sc.nextInt(); // Edge edge = a.new Edge(e,w); a.G[s].add(new Edge(e,w)); a.G[e].add(new Edge(s,w)); //双向连通 } a.djs(1); int ans = 0; for (int i = 2; i <= a.n; i++) { //没有结点0,本题1到1的距离还是0 ans += a.costo[i]; } System.out.println(ans); } public void djs(int s){ //初始化 for (int i = 0; i <= n; i++) { dis[i] = MAXINT; costo[i] = MAXINT; vis[i] = false; } //自己到自己肯定是0 dis[s] = 0; costo[s] = 0; // 是0不是s 本题不存在结点0 初始开始结点需要是1 vis[0] = true; //建立优先队列pq 存储Node结点信息 // Node comp = new Node(); //如果调用的是Comparator接口就这样写 // Queue<Node> pq = new PriorityQueue<Node>(comp); Queue<Node> pq = new PriorityQueue<Node>(); //初始化 pq.add(new Node(s,0)); Node temp; while(!pq.isEmpty()){ temp = pq.poll(); //从最近的开始取 取完删除 int v = temp.v; if(!vis[v]){ vis[v] = true; //看看你这个点v周围连了几个边 int length = G[v].size(); //对每个边循环一次 for (int i = 0; i < length; i++) { //目标点:vv int vv = G[v].get(i).v; if(vis[vv]) continue; //从点v到点vv 边长为cost int cost = G[v].get(i).w; //假如从v沿这条边到vv 那么就得到了新的权值 int newdis = dis[v] + cost; //eg:A->B=6 A->C=3 C->B=2 已经到C了 发现6>3+2=5 if(dis[vv] > newdis){ //那起始点A --->B 的距离就改成5了 dis[vv] = newdis; //目前要连通点B且满足最短路径条件 所需的最小花费就是2了 costo[vv] = cost; //v到VV的花费 //下一个,把点B放入pq中 pq.add(new Node(vv,dis[vv])); } //eg:A->B=5? 多种距离相同的方案,选取新边最小那个 if(dis[vv] == newdis){ costo[vv] = Math.min(costo[vv],cost); } } } } } }
相关文章推荐
- ccf 之交通规划 java版
- CCF CSP 201709-1 打酱油(Java-100分)
- CCF CSP 201612-2 工资计算(Java-100分)
- CCF CSP 201604-1 折点计数(Java-100分)
- CCF CSP 201703-2 学生排队(Java-100分)
- CCF CSP 201612-3 权限查询(Java-100分)
- CCF CSP 201609-1 最大波动(Java-100分)
- csp ccf 201612-3 权限查询java 100分
- CCF CSP 201509-1 数列分段(Java-100分)
- CCF CSP 最优灌溉 JAVA 201412_4 100分
- CCF CSP 201512-2 消除类游戏(Java-100分)
- CCF CSP 高速公路 JAVA 201509-4 100分
- CCF CSP 201609-4 交通规划
- CCF CSP 201712-2 游戏(Java-100分)
- CCF CSP 201509-2 日期计算(Java-100分)
- CCF CSP 公共钥匙盒 JAVA 201709-2 100分
- CCF CSP 201604-2 俄罗斯方块(Java-100分)
- CCF CSP 201609-3 炉石传说(Java-100分)
- CCF CSP 201712-1 最小差值(Java-100分)
- CCF CSP 201512-1 数位之和(Java-100分)