ALGO-4 结点选择 — 树型动态规划(java再优化版)

博主分享了在蓝桥OJ上遇到的ALGO-4结点选择问题,最初Java代码被判超时,通过研究C++版本并深入理解Java特性,最终成功用Java实现AC。优化主要集中在提高Java输入流的处理速度。文章提供了两种优化后的Java代码实现,并提到了String Tokenizer类的相关详情链接。

ALGO—4 结点选择

上篇的题解在最后提到,java的解法在蓝桥OJ上判为运行超时,改为C++后AC了。



在深度查阅了更多java的特性,并且试图用更java风格的算法进行优化后。最终用java也AC了。


其实主要处理的是java的输入流的速率问题。


以下附上两种优化方式的代码:(java再优化版)

第一种优化方式:

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

public class Main {
	final static int MAX = 100010;
	int edgecount;
	int tree[] = new int[MAX];
	int dp[][] = new int[MAX][2];
	int visit[] = new int[MAX * 2];
	boolean visited[] = new boolean[MAX];
	
	class Edge {
		int start, end, next;
		Edge(int s, int e, int n) {
			start = s;
			end = e;
			next = n;
		}
	}
	Edge edge[] = new Edge[MAX * 2];
	
	void add(int start, int end) {
		edge[edgecount] = new Edge(start, end, tree[start]);
		tree[start] = edgecount++;
	}

	void dfs(int x, int x_father) {
		Arrays.fill(visited, false);
		int temp = 0;
		visited[x] = true;
		visit[temp++] = x;
		while (temp > 0) {
			x = visit[temp - 1];
			boolean edgevisited = false;
			for (int i = tree[x]; i + 1 != 0; i = edge[i].next) {
				int end = edge[i].end;
				if (visited[end])
					continue;
				edgevisited = true;
				visit[temp++] = end;
				visited[end] = true;
			}
			if (edgevisited)
				continue;
			--temp;
			for (int i = tree[x]; i + 1 != 0; i = edge[i].next) {
				int x_son = edge[i].end;
				dp[x_son][0] += Math.max(dp[x][0], dp[x][1]);
				dp[x_son][1] += dp[x][0];

			}
		}
	}

	void run() throws IOException {
		int n = cin.nextInt();
		for (int i = 1; i <= n; ++i)
			dp[i][1] = cin.nextInt();
		Arrays.fill(tree, -1);
		for (int i = 1; i < n; ++i) {
			int x = cin.nextInt();
			int y = cin.nextInt();
			add(x, y);
			add(y, x);
		}
		dfs(1, 0);
		int ans = Math.max(dp[1][0], dp[1][1]);
		out.println(ans);
		out.close();
	}

	public static void main(String[] args) throws IOException {
		new Main().run();
	}

	Main() {
		cin = new InputReader(System.in);
		out = new PrintWriter(System.out);
	}

	InputReader cin;
	PrintWriter out;

	class InputReader {
		InputReader(InputStream in) {
			reader = new BufferedReader(new InputStreamReader(in));
			tokenizer = new StringTokenizer("");
		}

		private String next() throws IOException {
			while (!tokenizer.hasMoreTokens()) {
				tokenizer = new StringTokenizer(reader.readLine());
			}
			return tokenizer.nextToken();
		}

		public Integer nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		private BufferedReader reader;
		private StringTokenizer tokenizer;
	}
}


第二种优化方式:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

class Reader {
    static BufferedReader reader;
    static StringTokenizer tokenizer;

    static void init(InputStream input) {
        reader = new BufferedReader(new InputStreamReader(input));
        tokenizer = new StringTokenizer("");
    }

    static String next() throws IOException {
        while (!tokenizer.hasMoreTokens()) {
            tokenizer = new StringTokenizer(reader.readLine());
        }
        return tokenizer.nextToken();
    }

    static int nextInt() throws IOException {
        return Integer.parseInt(next());
    }

    static double nextDouble() throws IOException {
        return Double.parseDouble(next());
    }
}

public class Main {
	
	final static int MAX = 100010;
	static int edgecount;
	static int tree[] = new int[MAX];
	static int dp[][] = new int[MAX][2];
	static int visit[] = new int[MAX * 2];
	static boolean visited[] = new boolean[MAX];
	
	static class Edge {
		int start, end, next;
		Edge(int s, int e, int n) {
			start = s;
			end = e;
			next = n;
		}
	}
	static Edge edge[] = new Edge[MAX * 2];
	
	static void add(int start, int end) {
		edge[edgecount] = new Edge(start, end, tree[start]);
		tree[start] = edgecount++;
	}

	static void dfs(int x, int x_father) {
		Arrays.fill(visited, false);
		int temp = 0;
		visited[x] = true;
		visit[temp++] = x;
		while (temp > 0) {
			x = visit[temp - 1];
			boolean edgevisited = false;
			for (int i = tree[x]; i + 1 != 0; i = edge[i].next) {
				int end = edge[i].end;
				if (visited[end])
					continue;
				edgevisited = true;
				visit[temp++] = end;
				visited[end] = true;
			}
			if (edgevisited)
				continue;
			--temp;
			for (int i = tree[x]; i + 1 != 0; i = edge[i].next) {
				int x_son = edge[i].end;
				dp[x_son][0] += Math.max(dp[x][0], dp[x][1]);
				dp[x_son][1] += dp[x][0];

			}
		}
	}


	public static void main(String[] args) throws IOException {
		Reader.init(System.in);
		int n = Reader.nextInt();
		for (int i = 1; i <= n; ++i)
			dp[i][1] = Reader.nextInt();
		Arrays.fill(tree, -1);
		for (int i = 1; i < n; ++i) {
			int x = Reader.nextInt();
			int y = Reader.nextInt();
			add(x, y);
			add(y, x);
		}
		dfs(1, 0);
		int ans = Math.max(dp[1][0], dp[1][1]);
		System.out.println(ans);
	}
}


其中关于String Tokenizer类的介绍详见博文:http://blog.youkuaiyun.com/sobermineded/article/details/79299113

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值