ACM HDOJ 1869 (六度分离)

来源:互联网 发布:指纹算法 编辑:程序博客网 时间:2024/06/05 16:49

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1869

思路 把问题转化为最短路,即判断任意两个人之间的距离是否大于7

程序一 floyd 算法

import java.util.Arrays;import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scn = new Scanner(System.in);while (scn.hasNext()) {int pointsNumber = Integer.parseInt(scn.next());int edgesNumber = Integer.parseInt(scn.next());Floyd floyd = new Floyd(pointsNumber);for (int i = 0; i < edgesNumber; ++i) {int start = Integer.parseInt(scn.next());int end = Integer.parseInt(scn.next());int distance = 1;floyd.addEdge(start, end, distance);floyd.addEdge(end, start, distance);}floyd.calculateDistance();String result = "Yes";for (int i = 0; i < pointsNumber - 1; ++i) {for (int j = i + 1; j < pointsNumber; ++j) {if (7 < floyd.getMatrixItem(i, j)) {result = "No";break;}}if ("No".equals(result)) {break;}}System.out.println(result);}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 int getMatrixItem(int start, int end) {return matrix[start][end];}}
程序二 dijkstra 算法

import java.util.Arrays;import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scn = new Scanner(System.in);while (scn.hasNext()) {int pointsNumber = Integer.parseInt(scn.next());int edgesNumber = Integer.parseInt(scn.next());Dijkstra dijkstra = new Dijkstra(pointsNumber);for (int i = 0; i < edgesNumber; ++i) {int start = Integer.parseInt(scn.next());int end = Integer.parseInt(scn.next());int distance = 1;dijkstra.addEdge(start, end, distance);dijkstra.addEdge(end, start, distance);}String result = "Yes";for (int i = 0; i < pointsNumber; ++i) {int[] distance = dijkstra.calculateDistance(i);for (int j = 0; j < pointsNumber; ++j) {if (i != j && 7 < distance[j]) {result = "No";break;}}if ("No".equals(result)) {break;}}System.out.println(result);}scn.close();}}class Dijkstra {private final int INF = Integer.MAX_VALUE / 2;private int pointsNumber;private int[][] matrix;private boolean[] visit;private int[] resultDistance;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];}public void addEdge(int start, int end, int distance) {if (matrix[start][end] > distance) {matrix[start][end] = distance;}}public int[] calculateDistance(int initStart) {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) {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];}}}return resultDistance;}}
程序三 dijkstra 优先队列优化算法

import java.util.Arrays;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 = Integer.parseInt(scn.next());int edgesNumber = Integer.parseInt(scn.next());Dijkstra dijkstra = new Dijkstra(pointsNumber, edgesNumber * 2);for (int i = 0; i < edgesNumber; ++i) {int start = Integer.parseInt(scn.next());int end = Integer.parseInt(scn.next());int distance = 1;dijkstra.addEdge(start, end, distance);dijkstra.addEdge(end, start, distance);}String result = "Yes";for (int i = 0; i < pointsNumber; ++i) {int[] distance = dijkstra.calculateDistance(i);for (int j = 0; j < pointsNumber; ++j) {if (i != j && 7 < distance[j]) {result = "No";break;}}if ("No".equals(result)) {break;}}System.out.println(result);}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;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];}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) {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;}return resultDistance;}}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;}@Overridepublic 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.Scanner;public class Main {public static void main(String[] args) {Scanner scn = new Scanner(System.in);while (scn.hasNext()) {int pointsNumber = Integer.parseInt(scn.next());int edgesNumber = Integer.parseInt(scn.next());BellmanFord bellmanFord = new BellmanFord(pointsNumber,edgesNumber * 2);for (int i = 0; i < edgesNumber; ++i) {int start = Integer.parseInt(scn.next());int end = Integer.parseInt(scn.next());int distance = 1;bellmanFord.addEdge(start, end, distance);bellmanFord.addEdge(end, start, distance);}String result = "Yes";for (int i = 0; i < pointsNumber; ++i) {int[] distance = bellmanFord.calculateDistance(i);for (int j = 0; j < pointsNumber; ++j) {if (i != j && 7 < distance[j]) {result = "No";break;}}if ("No".equals(result)) {break;}}System.out.println(result);}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 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 pointsNumber, int edgesNumber) {this.pointsNumber = pointsNumber;this.edgesNumber = 0;edge = new Edge[edgesNumber];resultDistance = new int[pointsNumber];prePoint = new int[pointsNumber];}public void addEdge(int start, int end, int distance) {edge[edgesNumber++] = new Edge(start, end, distance);}public int[] calculateDistance(int initStart) {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())) {return null;}}return resultDistance;}}class Edge {private int start;private int end;private int distance;public Edge(int start, int end, int distance) {this.start = start;this.end = end;this.distance = distance;}public int getStart() {return start;}public int getEnd() {return end;}public int getDistance() {return distance;}}
程序五 spfa 算法

import java.util.Arrays;import java.util.LinkedList;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 = Integer.parseInt(scn.next());int edgesNumber = Integer.parseInt(scn.next());Spfa spfa = new Spfa(pointsNumber, edgesNumber * 2);for (int i = 0; i < edgesNumber; ++i) {int start = Integer.parseInt(scn.next());int end = Integer.parseInt(scn.next());int distance = 1;spfa.addEdge(start, end, distance);spfa.addEdge(end, start, distance);}String result = "Yes";for (int i = 0; i < pointsNumber; ++i) {int[] distance = spfa.calculateDistance(i);for (int j = 0; j < pointsNumber; ++j) {if (i != j && 7 < distance[j]) {result = "No";break;}}if ("No".equals(result)) {break;}}System.out.println(result);}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 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];}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) {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) {return null;}}}}return resultDistance;}}

0 0
原创粉丝点击