ACM HDOJ 2112 (HDU Today)
2014-01-17 23:14
281 查看
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2112
程序一 floyd 算法
程序二 dijkstra 算法
程序三 dijkstra 优先队列优化算法
程序四 bellman-ford 算法
程序五 spfa 算法
程序一 floyd 算法
import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scn = new Scanner(System.in); while (scn.hasNext()) { int pointsNumber = 0; int edgesNumber = Integer.parseInt(scn.next()); if (-1 == edgesNumber) { break; } Map<String, Integer> station = new HashMap<String, Integer>(); String initStartName = scn.next(); station.put(initStartName, pointsNumber++); String initEndName = scn.next(); if (!station.containsKey(initEndName)) { station.put(initEndName, pointsNumber++); } Edge[] edge = new Edge[edgesNumber]; for (int i = 0; i < edgesNumber; ++i) { String startName = scn.next(); String endName = scn.next(); int distance = Integer.parseInt(scn.next()); edge[i] = new Edge(startName, endName, distance); if (!station.containsKey(startName)) { station.put(startName, pointsNumber++); } if (!station.containsKey(endName)) { station.put(endName, pointsNumber++); } } Floyd floyd = new Floyd(pointsNumber); for (int i = 0; i < edgesNumber; ++i) { int start = station.get(edge[i].getStartName()); int end = station.get(edge[i].getEndName()); int distance = edge[i].getDistance(); floyd.addEdge(start, end, distance); floyd.addEdge(end, start, distance); } floyd.calculateDistance(); int initStart = station.get(initStartName); int initEnd = station.get(initEndName); int distance = floyd.getMatrixItem(initStart, initEnd); if (floyd.hasMinDistance(initStart, initEnd)) { System.out.println(distance); } else { System.out.println("-1"); } } scn.close(); } } class Floyd { private final int INF = Integer.MAX_VALUE / 2; private int pointsNumber; private int[][] matrix; public Floyd(int pointsNumber) { this.pointsNumber = pointsNumber; matrix = new int[pointsNumber][pointsNumber]; for (int i = 0; i < pointsNumber; ++i) { Arrays.fill(matrix[i], INF); matrix[i][i] = 0; } } public void addEdge(int start, int end, int distance) { if (matrix[start][end] > distance) { matrix[start][end] = distance; } } public void calculateDistance() { for (int k = 0; k < pointsNumber; ++k) { for (int i = 0; i < pointsNumber; ++i) { for (int j = 0; j < pointsNumber; ++j) { if (matrix[i][j] - matrix[i][k] > matrix[k][j]) { matrix[i][j] = matrix[i][k] + matrix[k][j]; } } } } } public boolean hasMinDistance(int start, int end) { if (INF <= matrix[start][end]) { return false; } else { return true; } } public int getMatrixItem(int start, int end) { return matrix[start][end]; } } class Edge { private String startName; private String endName; private int distance; public Edge(String startName, String endName, int distance) { this.startName = startName; this.endName = endName; this.distance = distance; } public String getStartName() { return startName; } public String getEndName() { return endName; } public int getDistance() { return distance; } }
程序二 dijkstra 算法
import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scn = new Scanner(System.in); while (scn.hasNext()) { int pointsNumber = 0; int edgesNumber = Integer.parseInt(scn.next()); if (-1 == edgesNumber) { break; } Map<String, Integer> station = new HashMap<String, Integer>(); String initStartName = scn.next(); station.put(initStartName, pointsNumber++); String initEndName = scn.next(); if (!station.containsKey(initEndName)) { station.put(initEndName, pointsNumber++); } Edge[] edge = new Edge[edgesNumber]; for (int i = 0; i < edgesNumber; ++i) { String startName = scn.next(); String endName = scn.next(); int distance = Integer.parseInt(scn.next()); edge[i] = new Edge(startName, endName, distance); if (!station.containsKey(startName)) { station.put(startName, pointsNumber++); } if (!station.containsKey(endName)) { station.put(endName, pointsNumber++); } } Dijkstra dijkstra = new Dijkstra(pointsNumber); for (int i = 0; i < edgesNumber; ++i) { int start = station.get(edge[i].getStartName()); int end = station.get(edge[i].getEndName()); int distance = edge[i].getDistance(); dijkstra.addEdge(start, end, distance); dijkstra.addEdge(end, start, distance); } int initStart = station.get(initStartName); int initEnd = station.get(initEndName); int distance = dijkstra.calculateDistance(initStart, initEnd); if (dijkstra.hasMinDistance()) { System.out.println(distance); } else { System.out.println("-1"); } } scn.close(); } } class Dijkstra { private final int INF = Integer.MAX_VALUE / 2; private int pointsNumber; private int[][] matrix; private boolean[] visit; private int[] resultDistance; private int resultMinDistance; public Dijkstra(int pointsNumber) { this.pointsNumber = pointsNumber; matrix = new int[pointsNumber][pointsNumber]; for (int i = 0; i < pointsNumber; ++i) { Arrays.fill(matrix[i], INF); matrix[i][i] = 0; } visit = new boolean[pointsNumber]; resultDistance = new int[pointsNumber]; resultMinDistance = INF; } public void addEdge(int start, int end, int distance) { if (matrix[start][end] > distance) { matrix[start][end] = distance; } } public int calculateDistance(int initStart, int initEnd) { Arrays.fill(visit, false); visit[initStart] = true; for (int i = 0; i < pointsNumber; ++i) { resultDistance[i] = matrix[initStart][i]; } for (int i = 0; i < pointsNumber; ++i) { int minDistance = INF; int minPoint = -1; for (int j = 0; j < pointsNumber; ++j) { if (!visit[j] && resultDistance[j] < minDistance) { minDistance = resultDistance[j]; minPoint = j; } } if (-1 == minPoint || minPoint == initEnd) { break; } visit[minPoint] = true; for (int j = 0; j < pointsNumber; ++j) { if (!visit[j] && resultDistance[j] - resultDistance[minPoint] > matrix[minPoint][j]) { resultDistance[j] = resultDistance[minPoint] + matrix[minPoint][j]; } } } resultMinDistance = resultDistance[initEnd]; return resultDistance[initEnd]; } public boolean hasMinDistance() { if (INF <= resultMinDistance) { return false; } else { return true; } } } class Edge { private String startName; private String endName; private int distance; public Edge(String startName, String endName, int distance) { this.startName = startName; this.endName = endName; this.distance = distance; } public String getStartName() { return startName; } public String getEndName() { return endName; } public int getDistance() { return distance; } }
程序三 dijkstra 优先队列优化算法
import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.PriorityQueue; import java.util.Queue; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scn = new Scanner(System.in); while (scn.hasNext()) { int pointsNumber = 0; int edgesNumber = Integer.parseInt(scn.next()); if (-1 == edgesNumber) { break; } Map<String, Integer> station = new HashMap<String, Integer>(); String initStartName = scn.next(); station.put(initStartName, pointsNumber++); String initEndName = scn.next(); if (!station.containsKey(initEndName)) { station.put(initEndName, pointsNumber++); } Edge[] edge = new Edge[edgesNumber]; for (int i = 0; i < edgesNumber; ++i) { String startName = scn.next(); String endName = scn.next(); int distance = Integer.parseInt(scn.next()); edge[i] = ne 4000 w Edge(startName, endName, distance); if (!station.containsKey(startName)) { station.put(startName, pointsNumber++); } if (!station.containsKey(endName)) { station.put(endName, pointsNumber++); } } Dijkstra dijkstra = new Dijkstra(pointsNumber, edgesNumber * 2); for (int i = 0; i < edgesNumber; ++i) { int start = station.get(edge[i].getStartName()); int end = station.get(edge[i].getEndName()); int distance = edge[i].getDistance(); dijkstra.addEdge(start, end, distance); dijkstra.addEdge(end, start, distance); } int initStart = station.get(initStartName); int initEnd = station.get(initEndName); int distance = dijkstra.calculateDistance(initStart, initEnd); if (dijkstra.hasMinDistance()) { System.out.println(distance); } else { System.out.println("-1"); } } scn.close(); } } class Dijkstra { private final int INF = Integer.MAX_VALUE / 2; private int pointsNumber; private int edgesNumber; private int[] edgesDistance; private int[] edgesEnd; private int[] nextStart; private int[] startMax; private boolean[] visit; private int[] resultDistance; private int[] prePoint; private int resultMinDistance; public Dijkstra(int pointsNumber, int edgesNumber) { this.pointsNumber = pointsNumber; this.edgesNumber = 0; edgesDistance = new int[edgesNumber]; edgesEnd = new int[edgesNumber]; nextStart = new int[edgesNumber]; startMax = new int[pointsNumber]; Arrays.fill(startMax, -1); visit = new boolean[pointsNumber]; resultDistance = new int[pointsNumber]; prePoint = new int[pointsNumber]; resultMinDistance = INF; } public void addEdge(int start, int end, int distance) { edgesDistance[edgesNumber] = distance; edgesEnd[edgesNumber] = end; nextStart[edgesNumber] = startMax[start]; startMax[start] = edgesNumber++; } public int calculateDistance(int initStart, int initEnd) { Arrays.fill(visit, false); Arrays.fill(resultDistance, INF); Arrays.fill(prePoint, -1); visit[initStart] = true; resultDistance[initStart] = 0; int currentPoint = initStart; Queue<Node> queue = new PriorityQueue<Node>(); for (int i = 1; i < pointsNumber; ++i) { for (int j = startMax[currentPoint]; j != -1; j = nextStart[j]) { int k = edgesEnd[j]; if (!visit[k] && resultDistance[currentPoint] < resultDistance[k] - edgesDistance[j]) { resultDistance[k] = resultDistance[currentPoint] + edgesDistance[j]; queue.offer(new Node(k, resultDistance[k])); prePoint[k] = currentPoint; } } while (!queue.isEmpty()) { Node node = queue.peek(); if (visit[node.getPoint()]) { queue.poll(); } else { break; } } if (queue.isEmpty()) { break; } currentPoint = queue.poll().getPoint(); visit[currentPoint] = true; if (currentPoint == initEnd) { break; } } resultMinDistance = resultDistance[initEnd]; return resultDistance[initEnd]; } public boolean hasMinDistance() { if (INF <= resultMinDistance) { return false; } else { return true; } } } class Edge { private String startName; private String endName; private int distance; public Edge(String startName, String endName, int distance) { this.startName = startName; this.endName = endName; this.distance = distance; } public String getStartName() { return startName; } public String getEndName() { return endName; } public int getDistance() { return distance; } public void setDistance(int distance) { this.distance = distance; } } class Node implements Comparable<Node> { private int point; private int distance; public Node(int point, int distance) { this.point = point; this.distance = distance; } public int getPoint() { return point; } public int getDistance() { return distance; } @Override public int compareTo(Node node) { if (this.distance > node.distance) { return 1; } else if (this.distance < node.distance) { return -1; } else { return this.point - node.point; } } }
程序四 bellman-ford 算法
import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scn = new Scanner(System.in); while (scn.hasNext()) { int pointsNumber = 0; int edgesNumber = Integer.parseInt(scn.next()); if (-1 == edgesNumber) { break; } Map<String, Integer> station = new HashMap<String, Integer>(); String initStartName = scn.next(); station.put(initStartName, pointsNumber++); String initEndName = scn.next(); if (!station.containsKey(initEndName)) { station.put(initEndName, pointsNumber++); } BellmanFord bellmanFord = new BellmanFord(edgesNumber * 2); for (int i = 0; i < edgesNumber; ++i) { String startName = scn.next(); String endName = scn.next(); int distance = Integer.parseInt(scn.next()); bellmanFord.addEdge(startName, endName, distance); bellmanFord.addEdge(endName, startName, distance); if (!station.containsKey(startName)) { station.put(startName, pointsNumber++); } if (!station.containsKey(endName)) { station.put(endName, pointsNumber++); } } for (int i = 0; i < bellmanFord.getEdgesNumber(); ++i) { bellmanFord.getEdgeItem(i).setStart( station.get(bellmanFord.getEdgeItem(i).getStartName())); bellmanFord.getEdgeItem(i).setEnd( station.get(bellmanFord.getEdgeItem(i).getEndName())); } bellmanFord.setPointsNumber(pointsNumber); int initStart = station.get(initStartName); int initEnd = station.get(initEndName); int distance = bellmanFord.calculateDistance(initStart, initEnd); if (bellmanFord.hasMinDistance()) { System.out.println(distance); } else { System.out.println("-1"); } } scn.close(); } } class BellmanFord { private final int INF = Integer.MAX_VALUE / 2; private int pointsNumber; private int edgesNumber; private Edge[] edge; private int[] resultDistance; private int[] prePoint; private int resultMinDistance; private boolean relax(int start, int end, int distance) { if (resultDistance[end] - distance > resultDistance[start]) { resultDistance[end] = resultDistance[start] + distance; prePoint[end] = start; return true; } else { return false; } } public BellmanFord(int edgesNumber) { pointsNumber = 0; this.edgesNumber = 0; edge = new Edge[edgesNumber]; resultDistance = null; prePoint = null; resultMinDistance = INF; } public void addEdge(String startName, String endName, int distance) { edge[edgesNumber++] = new Edge(startName, endName, distance, 0, 0); } public int calculateDistance(int initStart, int initEnd) { Arrays.fill(resultDistance, INF); Arrays.fill(prePoint, -1); resultDistance[initStart] = 0; for (int i = 1; i < pointsNumber; ++i) { Boolean flag = false; for (int j = 0; j < edgesNumber; ++j) { if (relax(edge[j].getStart(), edge[j].getEnd(), edge[j].getDistance())) { flag = true; } } if (!flag) { break; } } for (int i = 0; i < edgesNumber; ++i) { if (relax(edge[i].getStart(), edge[i].getEnd(), edge[i].getDistance())) { resultMinDistance = -INF; return -INF; } } resultMinDistance = resultDistance[initEnd]; return resultDistance[initEnd]; } public boolean hasMinDistance() { if (hasNegativeRing() || INF <= resultMinDistance) { return false; } else { return true; } } public boolean hasNegativeRing() { if (-INF >= resultMinDistance) { return true; } else { return false; } } public void setPointsNumber(int pointsNumber) { this.pointsNumber = pointsNumber; resultDistance = new int[pointsNumber]; prePoint = new int[pointsNumber]; } public int getEdgesNumber() { return edgesNumber; } public Edge getEdgeItem(int i) { return edge[i]; } } class Edge { private String startName; private String endName; private int distance; private int start; private int end; public Edge(String startName, String endName, int distance, int start, int end) { this.startName = startName; this.endName = endName; this.distance = distance; this.start = start; this.end = end; } public String getStartName() { return startName; } public String getEndName() { return endName; } public int getDistance() { return distance; } public void setDistance(int distance) { this.distance = distance; } public int getStart() { return start; } public void setStart(int start) { this.start = start; } public int getEnd() { return end; } public void setEnd(int end) { this.end = end; } }
程序五 spfa 算法
import java.util.Arrays; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Queue; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scn = new Scanner(System.in); while (scn.hasNext()) { int pointsNumber = 0; int edgesNumber = Integer.parseInt(scn.next()); if (-1 == edgesNumber) { break; } Map<String, Integer> station = new HashMap<String, Integer>(); String initStartName = scn.next(); station.put(initStartName, pointsNumber++); String initEndName = scn.next(); if (!station.containsKey(initEndName)) { station.put(initEndName, pointsNumber++); } Edge[] edge = new Edge[edgesNumber]; for (int i = 0; i < edgesNumber; ++i) { String startName = scn.next(); String endName = scn.next(); int distance = Integer.parseInt(scn.next()); edge[i] = new Edge(startName, endName, distance); if (!station.containsKey(startName)) { station.put(startName, pointsNumber++); } if (!station.containsKey(endName)) { station.put(endName, pointsNumber++); } } Spfa spfa = new Spfa(pointsNumber, edgesNumber * 2); for (int i = 0; i < edgesNumber; ++i) { int start = station.get(edge[i].getStartName()); int end = station.get(edge[i].getEndName()); int distance = edge[i].getDistance(); spfa.addEdge(start, end, distance); spfa.addEdge(end, start, distance); } int initStart = station.get(initStartName); int initEnd = station.get(initEndName); int distance = spfa.calculateDistance(initStart, initEnd); if (spfa.hasMinDistance()) { System.out.println(distance); } else { System.out.println("-1"); } } scn.close(); } } class Spfa { private final int INF = Integer.MAX_VALUE / 2; private int pointsNumber; private int edgesNumber; private int[] edgesDistance; private int[] edgesEnd; private int[] nextStart; private int[] startMax; private boolean[] visit; private int[] resultDistance; private int[] prePoint; private int[] count; private int resultMinDistance; private boolean relax(int start, int end, int distance) { if (resultDistance[end] - distance > resultDistance[start]) { resultDistance[end] = resultDistance[start] + distance; prePoint[end] = start; return true; } else { return false; } } public Spfa(int pointsNumber, int edgesNumber) { this.pointsNumber = pointsNumber; this.edgesNumber = 0; edgesDistance = new int[edgesNumber]; edgesEnd = new int[edgesNumber]; nextStart = new int[edgesNumber]; startMax = new int[pointsNumber]; Arrays.fill(startMax, -1); visit = new boolean[pointsNumber]; resultDistance = new int[pointsNumber]; prePoint = new int[pointsNumber]; count = new int[pointsNumber]; resultMinDistance = INF; } public void addEdge(int start, int end, int distance) { edgesDistance[edgesNumber] = distance; edgesEnd[edgesNumber] = end; nextStart[edgesNumber] = startMax[start]; startMax[start] = edgesNumber++; } public int calculateDistance(int initStart, int initEnd) { Arrays.fill(visit, false); Arrays.fill(resultDistance, INF); Arrays.fill(prePoint, -1); Arrays.fill(count, 0); visit[initStart] = true; resultDistance[initStart] = 0; ++count[initStart]; Queue<Integer> queue = new LinkedList<Integer>(); queue.offer(initStart); while (!queue.isEmpty()) { int start = queue.poll(); visit[start] = false; for (int i = startMax[start]; i != -1; i = nextStart[i]) { int end = edgesEnd[i]; if (relax(start, end, edgesDistance[i]) && !visit[end]) { queue.offer(end); visit[end] = true; if ((++count[end]) > pointsNumber) { resultMinDistance = -INF; return -INF; } } } } resultMinDistance = resultDistance[initEnd]; return resultDistance[initEnd]; } public boolean hasMinDistance() { if (hasNegativeRing() || INF <= resultMinDistance) { return false; } else { return true; } } public boolean hasNegativeRing() { if (-INF >= resultMinDistance) { return true; } else { return false; } } } class Edge { private String startName; private String endName; private int distance; public Edge(String startName, String endName, int distance) { this.startName = startName; this.endName = endName; this.distance = distance; } public String getStartName() { return startName; } public String getEndName() { return endName; } public int getDistance() { return distance; } }
相关文章推荐
- ACM学习历程—HDU 2112 HDU Today(map && spfa && 优先队列)
- HDOJ 2112 HDU Today (Dijstra 此题略坑)
- HDOJ 2112 HDU Today(最短路--dijkstra)
- HDOJ 题目2112 HDU Today(最短路径)
- HDOJ 2112 HDU Today
- hdoj 2112 HDU Today
- hdoj--2112 HDU Today(最短路径)
- HDOJ 2112 HDU Today (最短路 Dijkstra && SPFA)
- hdoj 2112 HDU Today
- hdoj 2112 HDU Today
- hdoj 2112 HDU Today
- HDOJ--2112--HDU Today
- HDOJ 题目2112 HDU Today(最短路径)
- HDOJ2112(HDU Today)
- hdoj 2112 HDU Today 【最短路】
- hdoj 2112 HDU Today
- HDOJ 2112 HDU Today
- HDOJ 2112 HDU Today (STL_map + dijkstra)
- HDOJ-2112-HDU Today 解题报告
- HDOJ-2112-HDU Today(最短路)