poj2395 解题报告

来源:互联网 发布:linux etc init.d 编辑:程序博客网 时间:2024/05/17 03:39

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 13605 Accepted: 5267
Description

The cows have run out of hay, a horrible event that must be remedied immediately. Bessie intends to visit the other farms to survey their hay situation. There are N (2 <= N <= 2,000) farms (numbered 1..N); Bessie starts at Farm 1. She’ll traverse some or all of the M (1 <= M <= 10,000) two-way roads whose length does not exceed 1,000,000,000 that connect the farms. Some farms may be multiply connected with different length roads. All farms are connected one way or another to Farm 1.

Bessie is trying to decide how large a waterskin she will need. She knows that she needs one ounce of water for each unit of length of a road. Since she can get more water at each farm, she’s only concerned about the length of the longest road. Of course, she plans her route between farms such that she minimizes the amount of water she must carry.

Help Bessie know the largest amount of water she will ever have to carry: what is the length of longest road she’ll have to travel between any two farms, presuming she chooses routes that minimize that number? This means, of course, that she might backtrack over a road in order to minimize the length of the longest road she’ll have to traverse.

Input

  • Line 1: Two space-separated integers, N and M.

  • Lines 2..1+M: Line i+1 contains three space-separated integers, A_i, B_i, and L_i, describing a road from A_i to B_i of length L_i.

Output

  • Line 1: A single integer that is the length of the longest road required to be traversed.

Sample Input

3 3
1 2 23
2 3 1000
1 3 43

Sample Output
43

Hint

OUTPUT DETAILS:

In order to reach farm 2, Bessie travels along a road of length 23. To reach farm 3, Bessie travels along a road of length 43. With capacity 43, she can travel along these roads provided that she refills her tank to maximum capacity before she starts down a road.

Source

USACO 2005 March Silver


解题思路:
由于是根据网上的解题分类找到的这一题,所以拿到手时已提前知道这是求MST最大边的问题。
在第一次求解的时候,采用了MatrixUDG+Prim算法,虽然使用题目给的数据通过,但提交之后一直为WA,不得解。
后通过复习union-find算法,并简单的学习了一下kruskal算法,+邻接表,AC,但是时间却达到了2000+ms,羞愧。由于这段代码是先写的kruskal问题再更改成这题的代码,所以在kruskal方法中,有些许无用代码段,但还是将解题代码贴上来。

解题代码
Kruskal+union-find,有关union-find的问题可查看之前的并查集博客。
(注释有时间后补齐)

import java.util.Arrays;import java.util.Scanner;public class Main{    private static Edge[] edges;    private static int[] id;    private static int[] sz;    private static int count;    public Main(int N, Edge[] edges) {        Main.edges = edges;        count = N;//顶点        id = new int[N];        sz = new int[N];        for (int i = 0; i < N; i++) {            id[i] = i;            sz[i] = 1;        }    }    public int find(int p) {        while (p != id[p]) p = id[p];        return p;    }    public boolean union(int p, int q) {        int i = find(p);        int j = find(q);        if (i == j) {            return false;        }        if (sz[i] < sz[j]) {            id[i] = j;            sz[j] += sz[i];        } else {            id[j] = i;            sz[i] += sz[j];        }        return true;    }    public int kruskal() {        Arrays.sort(edges);        int max = -1;        int elen = 0;        int sum = 0;        for (int i = 0; i < edges.length; ++i) {            if (union(edges[i].getStart(), edges[i].getDest())) {                elen++;                max = edges[i].getWeight();                sum += edges[i].getWeight();            }            if (elen == count - 1) {                System.out.println(max);                return sum;            }        }        return -1;    }    static class Edge implements Comparable<Edge> {        private int start;        private int dest;        private int weight;        public Edge(int start, int dest, int weight) {            this.start = start;            this.dest = dest;            this.weight = weight;        }        public int getStart() {            return start;        }        public int getDest() {            return dest;        }        public int getWeight() {            return weight;        }        @Override        public int compareTo(Edge o) {            if (this.weight > o.getWeight()) {                return 1;            }            if (this.getWeight() == o.getWeight()) {                return 0;            } else return -1;        }    public static void main(String[] args) {        Scanner scanner = new Scanner(System.in);        int farmNum = scanner.nextInt();        int routeNum = scanner.nextInt();        Edge[] edges = new Edge[routeNum];        for (int i = 0; i < routeNum; i++) {            int s = scanner.nextInt() - 1;            int d = scanner.nextInt() - 1;            int weight = scanner.nextInt();            edges[i] = new Edge(s, d, weight);        }        new Main(farmNum, edges).kruskal();    }}

顺便也将一直WA的prim算法的代码贴上来,如果大家能发现问题,还希望指出。

package poj;import java.util.Scanner;/** * MST的最大边 * Created by zzhy on 2016/1/12. */public class proj2395 {    private static final int INF = Integer.MAX_VALUE / 2;    private static int[][] matrix;    private static int prim() {        int start = 0;        int num = matrix.length;        int index = 0;        int[] weight = new int[num];        int[] route = new int[num];        route[index++] = 0;        //初始化weight        for (int i = 0; i < num; i++) {            weight[i] = matrix[start][i];        }        //遍历节点        for (int i = 0; i < num; i++) {            if (i == start) continue;            int k = minIndex(weight);            weight[k] = 0;            route[index++] = k;            //更新weight            for (int j = 0; j < num; j++) {                if (matrix[k][j] < weight[j]) {                    weight[j] = matrix[k][j];                }            }        }        int max = -1;        int min;        for (int i = 1; i < index; i++) {            int n = route[i];            min = INF;            for (int j = 0; j < i; j++) {                int m = route[j];                if (min > matrix[m][n]) {                    min = matrix[m][n];                }                //MST的最大边                if (max < min) {                    max = min;                }            }        }        return max;    }    private static int minIndex(int[] weight) {        int min = INF;        int index = -1;        for (int i = 0; i < weight.length; i++) {            if (weight[i] != 0 && weight[i] < min) {                min = weight[i];                index = i;            }        }        return index;    }    public static void main(String[] args) {        Scanner scanner = new Scanner(System.in);        int farmNum = scanner.nextInt();        int roadNum = scanner.nextInt();        matrix = new int[farmNum][farmNum];        //初始化matrix        for (int i = 0; i < farmNum; i++) {            for (int j = 0; j < farmNum; j++) {                if (i == j) matrix[i][j] = 0;                else {                    matrix[i][j] = INF;                }            }        }        //读取图        for (int i = 0; i < roadNum; i++) {            int m = scanner.nextInt() - 1;            int n = scanner.nextInt() - 1;            int l = scanner.nextInt();            if (matrix[m][n] > l) matrix[m][n] = matrix[n][m] = l;//            matrix[n][m] = matrix[m][n] = scanner.nextInt();        }        //打印图/*       for (int i = 0 ; i < farmNum ;i++) {            System.out.println(Arrays.toString(matrix[i]));        }*//*        System.out.println(prim());    }} */
0 0
原创粉丝点击