AcWing 3305. 作物杂交 java spfa

原题链接

🤠 题目分析

dijkstra 算法:贪心
Bellman-ford:BFS优化后就是 spfa
spfa算法:DP
floyd:DP

在这里插入图片描述

😋 spfa + 滚动数组优化空间


import java.io.*;
import java.util.*;

public class Main
{
	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
	static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
	static int N = 2010;
	static int M = 200010;
	static int n, m, k, t;
	// 邻接表存图
	static int[] w = new int[N];// 作物生长周期
	static int[] h = new int[N];
	static int[] e = new int[M];
	static int[] target = new int[M];// 作物可以合成的目标作物
	static int[] ne = new int[M];
	static int idx;

	static int[] dist = new int[N];//存最短路径的值
	static Queue<Integer> q = new LinkedList<>();//队列,用于记录最短路径被改变的点 
	static boolean[] st = new boolean[N];

	public static void main(String[] args) throws IOException
	{
		String[] split = in.readLine().split(" ");
		n = Integer.parseInt(split[0]);
		m = Integer.parseInt(split[1]);
		k = Integer.parseInt(split[2]);
		t = Integer.parseInt(split[3]);

//		生长周期
		String[] split2 = in.readLine().split(" ");
		for (int i = 1; i <= n; i++)//注意:1-n 号种子,下标从 1 开始
			w[i] = Integer.parseInt(split2[i - 1]);

//		已存在种子
		Arrays.fill(dist, 0x3f3f3f3f);
		String[] split3 = in.readLine().split(" ");
		for (int i = 0; i < m; i++)
		{
			int x = Integer.parseInt(split3[i]);
			dist[x] = 0;
			q.add(x);
			st[x] = true;
		}

		Arrays.fill(h, -1);
		for (int i = 0; i < k; i++)
		{
			String[] split4 = in.readLine().split(" ");
			int a = Integer.parseInt(split4[0]);
			int b = Integer.parseInt(split4[1]);
			int c = Integer.parseInt(split4[2]);
			add(a, b, c);
			add(b, a, c);
		}

		spfa();

		out.write(dist[t] + "");
		out.flush();
	}

	private static void spfa()
	{
		while (q.size() != 0)
		{
			int x = q.poll();
			st[x] = false;

			for (int i = h[x]; i != -1; i = ne[i])
			{
				int y = e[i];
				int z = target[i];
				if (dist[z] > Math.max(dist[x], dist[y]) + Math.max(w[x], w[y]))
				{
//					子作物各自的合成时间的最大值 + 子作物生长周期的最大值(合成 z 需要的时间)
					dist[z] = Math.max(dist[x], dist[y]) + Math.max(w[x], w[y]);
					if (!st[z])
					{
						q.add(z);
						st[z] = true;
					}
				}
			}
		}
	}

	/**
	 * a -> b = c 在 a 链表后边加上可以 一起杂交的作物,顺便把可以生成的作物也存在 b 对应下标的 target 数组中
	 * 
	 * @param a
	 * @param b
	 * @param c
	 */
	private static void add(int a, int b, int c)
	{
		e[idx] = b;
		target[idx] = c;
		ne[idx] = h[a];
		h[a] = idx++;
	}
}

🤠 dijkstra

未完待续……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值