CSP1712-4 行车路线 Java

int跑到70,long只能跑到80,double满分。

思路来自:https://www.cnblogs.com/goldlone/p/7979768.html

修改参考:http://www.cnblogs.com/whu-gbf/p/8515502.html

 

问题描述
  小明和小芳出去乡村玩,小明负责开车,小芳来导航。
  小芳将可能的道路分为大道和小道。大道比较好走,每走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
样例说明
  从1走小道到2,再走小道到3,疲劳度为52=25;然后从3走大道经过4到达5,疲劳度为20+30=50;最后从5走小道到6,疲劳度为1。总共为76。
数据规模和约定
  对于30%的评测用例,1 ≤ n ≤ 8,1 ≤ m ≤ 10;
  对于另外20%的评测用例,不存在小道;
  对于另外20%的评测用例,所有的小道不相交;
  对于所有评测用例,1 ≤ n ≤ 500,1 ≤ m ≤ 105,1 ≤ a, b ≤ n,t是0或1,c ≤ 105。保证答案不超过106。
import java.util.*;

public class Csp17124 {
    public static double dist[];// 当前到i走了多少小道。
    public static double exp[];// 1到i的劳累度
    public static boolean visited[];// 是否已经过
    public static double Max = Integer.MAX_VALUE;
    private static List<LinkedList<Edge1>> list = new ArrayList<LinkedList<Edge1>>();// 邻接表

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();// 路口数
        int m = sc.nextInt();// 道路数

        for (int i = 0; i < n + 1; i++) {
            list.add(new LinkedList<Edge1>());
        }
        dist = new double[n + 1];// 当前到i走了多少小道。
        exp = new double[n + 1];// 1到i的劳累度
        visited = new boolean[n + 1];// 是否已经过

        int lexp = 0;
        int t, a, b;
        double len;
        for (int i = 1; i <= m; i++) {

            t = sc.nextInt();
            a = sc.nextInt();
            b = sc.nextInt();
            len = sc.nextInt();
            list.get(a).push(new Edge1(t, a, b, len));
            list.get(b).push(new Edge1(t, b, a, len));
        }

        Arrays.fill(exp, Max);
        Arrays.fill(dist, 0);
        Arrays.fill(visited, false);

        dist[1] = 0;
        exp[1] = 0;
        visited[1] = true;
        int now = 1;

        while (!visited[n]) {// 只要n没被访问就一直走
            // 加边
            double tmpexp = Max;

            // System.out.println("now=" + now + " ");
            for (Edge1 edge : list.get(now)) {
                int i = edge.end;
                if (visited[i]) //不改成这样会超时
                    continue;

                if (edge.xiaodao == 1) {
                    tmpexp = exp[now] - Math.pow(dist[now], 2) + Math.pow(dist[now] + edge.len, 2);
                    if (tmpexp < exp[i]) {
                        dist[i] = dist[now] + edge.len;
                        exp[i] = tmpexp;
                        // System.out.println("修改"+i+"的exp为"+exp[i]+"
                        // 修改dist为"+dist[i]);
                    }
                } else {
                    tmpexp = exp[now] + edge.len;
                    if (exp[now] + edge.len < exp[i]) {
                        dist[i] = 0;
                        exp[i] = tmpexp;
                        // System.out.println("修改"+i+"的exp为"+exp[i]);
                    }
                }

            }

            lexp = 0;
            for (int i1 = 1; i1 <= n; i1++) {
                if (!visited[i1] && exp[i1] < exp[lexp]) {
                    lexp = i1;
                }
            }
            if (lexp == 0)
                break;
            now = lexp;
            visited[now] = true;

        }

        System.out.print((long) exp[n]);

    }

}

class Edge1 {
    public int xiaodao = 1;
    public double len;
    public int start;
    public int end;

    public Edge1(int xiaodao, int start, int end, double len) {
        this.xiaodao = xiaodao;
        this.start = start;
        this.end = end;
        this.len = len;
    }
}

 

posted @ 2018-03-12 14:35  保暖婆婆  阅读(360)  评论(0编辑  收藏  举报