ACM HDOJ 2066 (一个人的旅行)
2014-01-17 23:03
309 查看
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2066
思路 添加超级始点和超级终点,求超级始点到超级终点的最短路
程序一 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 = 1002;
int edgesNumber = Integer.parseInt(scn.next());
int startNumber = Integer.parseInt(scn.next());
int endNumber = 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 = Integer.parseInt(scn.next());
dijkstra.addEdge(start, end, distance);
dijkstra.addEdge(end, start, distance);
}
int initStart = 0;
int initEnd = 1001;
for (int i = 0; i < startNumber; ++i) {
int start = Integer.parseInt(scn.next());
dijkstra.addEdge(initStart, start, 0);
}
for (int i = 0; i < endNumber; ++i) {
int end = Integer.parseInt(scn.next());
dijkstra.addEdge(end, initEnd, 0);
}
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;
}
}
}
程序二 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 = 1002;
int edgesNumber = Integer.parseInt(scn.next());
int startNumber = Integer.parseInt(scn.next());
int endNumber = Integer.parseInt(scn.next());
Dijkstra dijkstra = new Dijkstra(pointsNumber, edgesNumber * 2
+ startNumber + endNumber);
for (int i = 0; i < edgesNumber; ++i) {
int start = Integer.parseInt(scn.next());
int end = Integer.parseInt(scn.next());
int distance = Integer.parseInt(scn.next());
dijkstra.addEdge(start, end, distance);
dijkstra.addEdge(end, start, distance);
}
int initStart = 0;
int initEnd = 1001;
for (int i = 0; i < startNumber; ++i) {
int start = Integer.parseInt(scn.next());
dijkstra.addEdge(initStart, start, 0);
}
for (int i = 0; i < endNumber; ++i) {
int end = Integer.parseInt(scn.next());
dijkstra.addEdge(end, initEnd, 0);
}
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 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.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scn = new Scanner(System.in);
while (scn.hasNext()) {
int pointsNumber = 1002;
int edgesNumber = Integer.parseInt(scn.next());
int startNumber = Integer.parseInt(scn.next());
int endNumber = Integer.parseInt(scn.next());
BellmanFord bellmanFord = new BellmanFord(pointsNumber, edgesNumber
* 2 + startNumber + endNumber);
for (int i = 0; i < edgesNumber; ++i) {
int start = Integer.parseInt(scn.next());
int end = Integer.parseInt(scn.next());
int distance = Integer.parseInt(scn.next());
bellmanFord.addEdge(start, end, distance);
bellmanFord.addEdge(end, start, distance);
}
int initStart = 0;
int initEnd = 1001;
for (int i = 0; i < startNumber; ++i) {
int start = Integer.parseInt(scn.next());
bellmanFord.addEdge(initStart, start, 0);
}
for (int i = 0; i < endNumber; ++i) {
int end = Integer.parseInt(scn.next());
bellmanFord.addEdge(end, initEnd, 0);
}
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 pointsNumber, int edgesNumber) {
this.pointsNumber = pointsNumber;
this.edgesNumber = 0;
edge = new Edge[edgesNumber];
resultDistance = new int[pointsNumber];
prePoint = new int[pointsNumber];
resultMinDistance = INF;
}
public void addEdge(int start, int end, int distance) {
edge[edgesNumber++] = new Edge(start, end, distance);
}
public int calculateDistan
b923
ce(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;
}
}
}
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 = 1002;
int edgesNumber = Integer.parseInt(scn.next());
int startNumber = Integer.parseInt(scn.next());
int endNumber = Integer.parseInt(scn.next());
Spfa spfa = new Spfa(pointsNumber, edgesNumber * 2 + startNumber
+ endNumber);
for (int i = 0; i < edgesNumber; ++i) {
int start = Integer.parseInt(scn.next());
int end = Integer.parseInt(scn.next());
int distance = Integer.parseInt(scn.next());
spfa.addEdge(start, end, distance);
spfa.addEdge(end, start, distance);
}
int initStart = 0;
int initEnd = 1001;
for (int i = 0; i < startNumber; ++i) {
int start = Integer.parseInt(scn.next());
spfa.addEdge(initStart, start, 0);
}
for (int i = 0; i < endNumber; ++i) {
int end = Integer.parseInt(scn.next());
spfa.addEdge(end, initEnd, 0);
}
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;
}
}
}
思路 添加超级始点和超级终点,求超级始点到超级终点的最短路
程序一 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 = 1002;
int edgesNumber = Integer.parseInt(scn.next());
int startNumber = Integer.parseInt(scn.next());
int endNumber = 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 = Integer.parseInt(scn.next());
dijkstra.addEdge(start, end, distance);
dijkstra.addEdge(end, start, distance);
}
int initStart = 0;
int initEnd = 1001;
for (int i = 0; i < startNumber; ++i) {
int start = Integer.parseInt(scn.next());
dijkstra.addEdge(initStart, start, 0);
}
for (int i = 0; i < endNumber; ++i) {
int end = Integer.parseInt(scn.next());
dijkstra.addEdge(end, initEnd, 0);
}
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;
}
}
}
程序二 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 = 1002;
int edgesNumber = Integer.parseInt(scn.next());
int startNumber = Integer.parseInt(scn.next());
int endNumber = Integer.parseInt(scn.next());
Dijkstra dijkstra = new Dijkstra(pointsNumber, edgesNumber * 2
+ startNumber + endNumber);
for (int i = 0; i < edgesNumber; ++i) {
int start = Integer.parseInt(scn.next());
int end = Integer.parseInt(scn.next());
int distance = Integer.parseInt(scn.next());
dijkstra.addEdge(start, end, distance);
dijkstra.addEdge(end, start, distance);
}
int initStart = 0;
int initEnd = 1001;
for (int i = 0; i < startNumber; ++i) {
int start = Integer.parseInt(scn.next());
dijkstra.addEdge(initStart, start, 0);
}
for (int i = 0; i < endNumber; ++i) {
int end = Integer.parseInt(scn.next());
dijkstra.addEdge(end, initEnd, 0);
}
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 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.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scn = new Scanner(System.in);
while (scn.hasNext()) {
int pointsNumber = 1002;
int edgesNumber = Integer.parseInt(scn.next());
int startNumber = Integer.parseInt(scn.next());
int endNumber = Integer.parseInt(scn.next());
BellmanFord bellmanFord = new BellmanFord(pointsNumber, edgesNumber
* 2 + startNumber + endNumber);
for (int i = 0; i < edgesNumber; ++i) {
int start = Integer.parseInt(scn.next());
int end = Integer.parseInt(scn.next());
int distance = Integer.parseInt(scn.next());
bellmanFord.addEdge(start, end, distance);
bellmanFord.addEdge(end, start, distance);
}
int initStart = 0;
int initEnd = 1001;
for (int i = 0; i < startNumber; ++i) {
int start = Integer.parseInt(scn.next());
bellmanFord.addEdge(initStart, start, 0);
}
for (int i = 0; i < endNumber; ++i) {
int end = Integer.parseInt(scn.next());
bellmanFord.addEdge(end, initEnd, 0);
}
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 pointsNumber, int edgesNumber) {
this.pointsNumber = pointsNumber;
this.edgesNumber = 0;
edge = new Edge[edgesNumber];
resultDistance = new int[pointsNumber];
prePoint = new int[pointsNumber];
resultMinDistance = INF;
}
public void addEdge(int start, int end, int distance) {
edge[edgesNumber++] = new Edge(start, end, distance);
}
public int calculateDistan
b923
ce(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;
}
}
}
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 = 1002;
int edgesNumber = Integer.parseInt(scn.next());
int startNumber = Integer.parseInt(scn.next());
int endNumber = Integer.parseInt(scn.next());
Spfa spfa = new Spfa(pointsNumber, edgesNumber * 2 + startNumber
+ endNumber);
for (int i = 0; i < edgesNumber; ++i) {
int start = Integer.parseInt(scn.next());
int end = Integer.parseInt(scn.next());
int distance = Integer.parseInt(scn.next());
spfa.addEdge(start, end, distance);
spfa.addEdge(end, start, distance);
}
int initStart = 0;
int initEnd = 1001;
for (int i = 0; i < startNumber; ++i) {
int start = Integer.parseInt(scn.next());
spfa.addEdge(initStart, start, 0);
}
for (int i = 0; i < endNumber; ++i) {
int end = Integer.parseInt(scn.next());
spfa.addEdge(end, initEnd, 0);
}
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;
}
}
}
相关文章推荐
- HDOJ 2066 HDU 2066 一个人的旅行 ACM 2066 IN HDU
- hdoj 2066 一个人的旅行 【多源多汇最短路】
- hdoj.2066 一个人的旅行 20141107
- HDOJ 2066 一个人的旅行(最短路之SPFA)
- HDOJ 2066 一个人的旅行 (多次求单源最短路径)
- hdoj 2066 一个人的旅行
- hdoj 2066 一个人的旅行
- HDOJ 2066 一个人的旅行 (Dijkstra)
- HDOJ 2066 一个人的旅行(最短路,dijkstra算法)
- [HDOJ2066]一个人的旅行
- HDOJ---2066 一个人的旅行[Dijkstra算法]
- hdoj 2066 一个人的旅行(dijkstra)多源点多
- HDOJ 2066 一个人的旅行 (Dijkstra算法)
- hdoj 2066 一个人的旅行
- HDOJ-2066一个人的旅行
- hdoj2066一个人的旅行
- HDOJ 2066 一个人的旅行 (Dijkstra)
- HDOJ-2066 一个人的旅行 ------floyd
- ACM->dijkstra + heap + stl 一个人的旅行 hdu 2066
- Flody算法--HDOJ-2066 -- 一个人的旅行