ALGO-4 结点选择 — 树型动态规划(java再优化版)
2018-02-09 15:26
190 查看
ALGO—4 结点选择
上篇的题解在最后提到,java的解法在蓝桥OJ上判为运行超时,改为C++后AC了。
![](https://img-blog.csdn.net/20180209152338564?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc29iZXJtaW5lZGVk/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
![](https://img-blog.csdn.net/20180209152326239?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc29iZXJtaW5lZGVk/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
在深度查阅了更多java的特性,并且试图用更java风格的算法进行优化后。最终用java也AC了。
![](https://img-blog.csdn.net/20180209152308375?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc29iZXJtaW5lZGVk/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
其实主要处理的是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.csdn.net/sobermineded/article/details/79299113
上篇的题解在最后提到,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.csdn.net/sobermineded/article/details/79299113
相关文章推荐
- ALGO-4 结点选择 — 树型动态规划(java)
- Java 冒泡排序算法-优化选择
- 蓝桥杯ALGO_04(结点选择)
- ALGO-3 K好数 — 动态规划(java)
- 蓝桥杯 ALGO-4 结点选择 (树形动态规划)
- 算法-蓝桥杯-算法训练 结点选择(JAVA)
- 蓝桥杯 ALGO-4 结点选择(树形动态规划)
- java性能优化--List选择及优化
- 蓝桥杯 ALGO-4 算法训练 结点选择
- 算法笔记_076:蓝桥杯练习 结点选择(Java)
- java实现选择、插入、归并、快速排序以及优化
- java 数组中两数之差的最大值 蛮力算法 动态规划及其优化
- 蓝桥杯练习系统 ALGO-4 结点选择
- Java高级篇 -- List选择及优化
- 【树形DP】蓝桥杯 ALGO-4 结点选择
- 蓝桥杯 - 算法训练 - ALGO - 4 结点选择 (经典树形DP)
- Java高级篇 -- List选择及优化
- Java高级篇 -- List选择及优化
- java版排序算法简介及冒泡排序以及优化,选择排序,直接插入排序,希尔排序,堆排序,快速排序及其优化前言 2 分类 2 稳定性 3 时间复杂度 4 Java实现版本 5 1、冒泡排序 6 2、选择排序
- java 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。