Dijkstra算法,使之能够输出顶点1到每个顶点的最短距离和路径。
算法输入:正整数n,图的顶点数
正整数m,图的边数
m个3元组,每个三元组依次为边的起点、终点和长度
算法输出:n行,每行依次输出顶点1到各个顶点的最短距离和路径。
import java.util.*;
public class dijkstra {
static int inf = (int) 9e5;
static class Node implements Comparable<Node> {
int id;
int distance;
public Node(int id, int distance) {
this.id = id;
this.distance = distance;
}
public int compareTo(Node other) {
return Integer.compare(this.distance, other.distance);
}
}
public static void dijkstra(int n, int m, int[][] edges) {
int[][] g = new int[n][n];
for (int i = 0; i < n; i++) {
Arrays.fill(g[i], inf);
}
for (int i = 0; i < m; i++) {
int u = edges[i][0] - 1;
int v = edges[i][1] - 1;
int weight = edges[i][2];
g[u][v] = weight;
}
int[] distance = new int[n];
int[] prev = new int[n];
Arrays.fill(distance, inf);
Arrays.fill(prev, -1);
distance[0] = 0;
PriorityQueue<Node> pq = new PriorityQueue<>();
pq.offer(new Node(0, 0));
while (!pq.isEmpty()) {
Node curr = pq.poll();
int u = curr.id;
int dist = curr.distance;
if (dist > distance[u]) {
continue;
}
for (int v = 0; v < n; v++) {
if (g[u][v] != inf && dist + g[u][v] < distance[v]) {
distance[v] = dist + g[u][v];
prev[v] = u;
pq.offer(new Node(v, distance[v]));
}
}
}
printShortestPaths(distance, prev);
}
public static void printShortestPaths(int[] distance, int[] prev) {
int n = distance.length;
for (int i = 0; i < n; i++) {
if (i == 0) {
System.out.println("1到1的最短路径为:0");
System.out.println("路径为:1");
}else {
int d = distance[i];
if (d == inf) {
System.out.println("1到"+(i+1)+"的最短距离为:无路径");
} else {
StringBuilder path = new StringBuilder();
int curr = i;
while (curr != 0) {
path.insert(0, curr + 1).insert(0,"->");
curr = prev[curr];
}
path.insert(0, "1");
System.out.println("1到"+(i+1)+"的最短距离为:"+d);
System.out.println("路径为:"+path.toString());
}
}
}
}
public static void main(String[] args) {
int n = 6;
int m = 9;
int[][] edges = {
{1,2,1},
{1,3,12},
{2,3,9},
{2,4,3},
{3,5,5},
{4,3,4},
{4,5,13},
{4,6,15},
{5,6,4},
};
dijkstra(n, m, edges);
}
}
//
若干人到河边,需划船过河,只有一条船,且每次只能容纳两人,船过河后需有一人将船划回。每人过河的速度不同,两人同时划船速度取决于较慢的人的速度,最少需多少时间让所有人都过河。
算法输入:正整数n(需过河的人数)
n个正整数(每人过河的速度,以空格隔开)
算法输出:所有人过河最少的时间
【输入实例1】
4
1 2 5 10
【输出实例1】
17
import java.util.Arrays;
import java.util.Scanner;
public class Test {
static int guoHe(int speed[]) {
Arrays.sort(speed);
int time = 0;
int n = speed.length;
while (n > 3) {
time += Math.min(2*speed[1], speed[0]+speed[n-2]);
time += speed[0] + speed[n-1];
n -= 2;
}
if (n == 3)
time += speed[0] + speed[1] + speed[2];
if (n == 2)
time += speed[1];
if (n == 1)
time += speed[0];
return time;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int s[] = new int[n];
for (int i = 0; i < n; i++)
s[i] = input.nextInt();
System.out.println(guoHe(s));
}
}
//
田忌赛马:齐王和田忌赛马,每人各派n匹马,每场比赛,输的一方要给赢的一方200两黄金,如平局,双方都不拿钱。
算法输入:正整数n(马的数量)
n个正整数(表示田忌马的速度)
n个正整数(表示齐王马的速度)
算法输出:田忌赛马可能赢得最多的黄金数。
【输入实例1】
3
92 83 74
95 87 74
【输出实例1】
200
import java.util.Arrays;
import java.util.Scanner;
public class TianJiRacing {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] tianjiHorses = new int[n];
int[] kingHorses = new int[n];
for (int i = 0; i < n; i++) {
tianjiHorses[i] = scanner.nextInt();
}
for (int i = 0; i < n; i++) {
kingHorses[i] = scanner.nextInt();
}
Arrays.sort(tianjiHorses);
Arrays.sort(kingHorses);
int maxProfit = maximizeProfit(tianjiHorses, kingHorses, n);
System.out.println(maxProfit);
scanner.close();
}
private static int maximizeProfit(int[] tianji, int[] king, int n) {
int tianjiIndex = 0;
int kingIndex = 0;
int tianjiMinIndex = 0;
int profit = 0;
while (tianjiIndex < n) {
if (tianji[tianjiIndex] > king[kingIndex]) {
profit += 200;
kingIndex++;
tianjiIndex++;
}
else {
tianjiIndex++;
}
}
return profit-200;
}
}
//
用归纳法设计算法,在n个元素的数组中寻找最大值。
算法输入:正整数n(元素个数)
n个正整数(其间以空格隔开)
算法输出:n个正整数中的最大值
输入实例:8
3 5 10 100 39 38 80 70
输出实例:100
import java.util.Scanner;
public class U5_1 {
static int getMax(int a[], int s) {
int n = a.length;
if (n-1 == s)
return a[s];
else {
int tmp = getMax(a, s+1);
return tmp > a[s] ? tmp : a[s];
}
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int a[] = new int[n];
for (int i = 0; i < n; i++)
a[i] = input.nextInt();
System.out.print(getMax(a, 0));
}
}
//
给定一个十进制正整数,归纳法设计算法,从高到低输出各位数字
算法输入:正整数n(0<n<230)
算法输出:从高位到低位逐位输出各位数字,数字之间有空格
输入实例:513810
输出实例:5 1 3 8 1 0
import java.util.Scanner;
public class U5_2 {
static void print(int n) {
if (n > 9)
print(n / 10);
System.out.print((n % 10) + " ");
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt();
print(n);
}
}
//
使用回溯法生成自然数1~n的所有不重复的排列。
算法输入:整数n
算法输出:输出n的全排列。
【输入实例1】
3
【输出实例1】
123 132 213 231 312 321
import java.util.Scanner;
public class Unit16 {
public static void print(int a[], int n) {
for (int i = 1; i <= n; i++)
System.out.print(a[i]);
System.out.println();
}
public static boolean check(int a[], int k) {
for (int i = 1; i < k; i++)
if (a[i] == a[k])
return false;
return true;
}
public static void perm(int n) {
int a[] = new int[10];
int k = 1;
while (k > 0) {
while (a[k] < n) {
a[k]++;
if (check(a, k) && k == n)
print(a, k);
else if (check(a, k) && k < n)
k++;
}
a[k] = 0;
k--;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
perm(n);
}
}
//
有2n个同学参加拔河比赛。要求参赛的两组同学体重之和相等。
算法输入:整数n(1<n<20)。
2*n个整数,表示每个同学的体重。
算法输出:所有符合要求的分组。
【输入实例】
6
48 43 57 64 50 52 18 34 39 56 16 61
【输出实例】
48 43 57 64 18 39 50 52 34 56 16 61
...
import java.util.Scanner;
public class Unit17 {
public static void divide(int weight[]) {
int n = weight.length;
int totalWeight = 0;
for (int i = 0; i < n; i++) {
totalWeight += weight[i];
}
int avgWeight = totalWeight / 2;
int c[] = new int[n];
int k = 0;
while (k >= 0) {
while (c[k] < 2) {
c[k]++;
int sum = 0;
int count = 0;
for (int i = 0; i < n; i++)
if (c[i] == 1) {
sum += weight[i];
count++;
}
if (sum == avgWeight & &count == n/2) {
for (int i = 0; i < n; i++) {
if (c[i] == 1)
System.out.print
(weight[i] + " ");
}
System.out.print(" ");
for (int i = 0; i < n; i++) {
if (c[i] != 1)
System.out.print
(weight[i] + " ");
}
System.out.println();
}
else if (sum < avgWeight && count < n/2 && k < n-1)
{
k++;
}
else if (sum < avgWeight && (k == n-1 || count >= n/2))
break;
}
c[k] = 0;
k--;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int weight[] = new int[2*n];
for (int i = 0; i < 2*n; i++)
weight[i] = sc.nextInt();
divide(weight);
}}