zoukankan      html  css  js  c++  java
  • CCF CSP 20171204 行车路线 JAVA 100分代码

    12月的CSP的第四题在网上始终找不到满分的java代码,我在这位大佬的代码的基础上进行了一些修改,终于跑到了满分

    大佬代码链接如下:  CCF CSP 20171203 行车路线 JAVA(70分)

    问题描述
    
      小明和小芳出去乡村玩,小明负责开车,小芳来导航。
       小芳将可能的道路分为大道和小道。大道比较好走,每走1公里小明会增加1的疲劳度。小道不好走,如果连续走小道,小明的疲劳值会快速增加,连续走s公里小明会增加s2的疲劳度。
       例如:有5个路口,1号路口到2号路口为小道,2号路口到3号路口为小道,3号路口到4号路口为大道,4号路口到5号路口为小道,相邻路口之间的距离都是2公里。如果小明从1号路口到5号路口,则总疲劳值为(2+2)2+2+22=16+2+4=22。
       现在小芳拿到了地图,请帮助她规划一个开车的路线,使得按这个路线开车小明的疲劳度最小。
    
    输入格式
    
      输入的第一行包含两个整数n, m,分别表示路口的数量和道路的数量。路口由1至n编号,小明需要开车从1号路口到n号路口。
       接下来m行描述道路,每行包含四个整数t, a, b, c,表示一条类型为t,连接a与b两个路口,长度为c公里的双向道路。其中t为0表示大道,t为1表示小道。保证1号路口和n号路口是连通的。
    
    输出格式
    
      输出一个整数,表示最优路线下小明的疲劳度。
    
    样例输入
    
    6 7
     1 1 2 3
     1 2 3 2
     0 1 3 30
     0 3 4 20
     0 4 5 30
     1 3 5 6
     1 5 6 1
    
    样例输出
    
    76
    package csp;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Scanner;
    
    public class Main_201712_4 {
        private static int n;
        private final static int MAX = Integer.MAX_VALUE;
        private static boolean[] finalVex;
        private static double[] shortPath;
        private static List<LinkedList<Edge>> list;
        
        public static void main(String[] args) {
            //准备工作
            Scanner in = new Scanner(System.in);
            n = in.nextInt();
            int nums = in.nextInt();
            list = new ArrayList<>();
            for(int i=0; i<n; i++) {
                list.add(new LinkedList<Edge>());
            }
            for(int i=0; i<nums; i++) {
                int type = in.nextInt();
                int start = in.nextInt();
                int end = in.nextInt();
                int weight = in.nextInt();
                list.get(start-1).add(new Edge(type, start-1, end-1, weight));
                list.get(end-1).add(new Edge(type, end-1, start-1, weight));
            }
            //核心代码
            shortPathDij();
            if(n == 1) {
                System.out.println(0);
            }else {
                System.out.println((long)shortPath[n-1]);
            }
            //关闭流
            in.close();
        }
        
        public static void shortPathDij() {
            Edge tmp = null;
            shortPath = new double[n];
            int[] tails = new int[n];
            int[] exp = new int[n];
            finalVex = new boolean[n];
            Arrays.fill(shortPath, MAX);
            Arrays.fill(finalVex, false);
            Arrays.fill(exp, 0);
            
            shortPath[0] = 0;
            tails[0] = 1;
            while(!finalVex[n-1]) {
                int index = min(shortPath);
                if(index == -1)
                    break;
                LinkedList<Edge> p = list.get(index);//获得从index位置出发的所有边
                Iterator<Edge> it = p.iterator();// 上述边的迭代器
                int j=0;
                while(it.hasNext()) {//遍历这些边
                    tmp = it.next();//拿到一条边
                    j = tmp.end;// j为这条边的终点
                    if(finalVex[j])
                        continue;
                    if(tmp.type==1) {//如果边是小路
                        int eee = exp[index]+tmp.weight;
                        double sum = shortPath[index]-(int)Math.pow(exp[index], 2)+(int)Math.pow(eee, 2);
                        if(sum<shortPath[j]) {
                            shortPath[j] = sum;
                            tails[j] = index+1;
                            exp[j] = eee;
                        }
                    } else {//如果边是大路
                        if((shortPath[index]+tmp.weight)<shortPath[j]) {
                            shortPath[j] = shortPath[index]+tmp.weight;
                            tails[j] = index+1;
                            exp[j] = 0;
                        }
                    }
                }
            }
        }
        private static int min(double[] shortPath2) {
            int index = -1;
            for(int i=0; i<n; i++) 
                if(!finalVex[i])
                    index = i;
            if(index==-1)
                return -1;
            for(int i=0; i<shortPath2.length; i++)
                if(shortPath2[index]>shortPath2[i]&&!finalVex[i])
                    index = i;
            finalVex[index] = true;
            return index;
        }
        
    }
    
    class Edge{
        public int type;
        public int start;
        public int end;
        public int weight;
        public Edge(int type, int start, int end, int weight) {
            this.type = type;
            this.start = start;
            this.end = end;
            this.weight = weight;
        }
    }
  • 相关阅读:
    (二分查找 拓展) leetcode 69. Sqrt(x)
    (二分查找 拓展) leetcode 162. Find Peak Element && lintcode 75. Find Peak Element
    (链表) lintcode 219. Insert Node in Sorted Linked List
    (二分查找 拓展) leetcode 34. Find First and Last Position of Element in Sorted Array && lintcode 61. Search for a Range
    (最短路 Floyd) P2910 [USACO08OPEN]寻宝之路Clear And Present Danger 洛谷
    (字符串 数组 递归 双指针) leetcode 344. Reverse String
    (二叉树 DFS 递归) leetcode 112. Path Sum
    (二叉树 DFS 递归) leetcode 101. Symmetric Tree
    (二叉树 递归) leetcode 144. Binary Tree Preorder Traversal
    (二叉树 递归 DFS) leetcode 100. Same Tree
  • 原文地址:https://www.cnblogs.com/whu-gbf/p/8515502.html
Copyright © 2011-2022 走看看