笔记2024.6.6

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);

}}

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值