【树形DP】HDU 2196 Computer
通道:http://acm.hdu.edu.cn/showproblem.php?pid=2196
题意:题意是求树中每个点的最大距离值是多少。
思路:
2遍DFS,对于每个父节点,求出子树的最大和次大儿子,然后更新的时候就是这个点要么是儿子所贡献,要么是父亲来的点贡献,记录最大与次大是区分但是父亲贡献的答案的时侯避免走的就是最大儿子。
代码:
import java.io.*; import java.util.*; public class Main { static final int MAX_N = 10007; class Edge { int u, v, w, nxt; Edge () { } Edge (int _u, int _v, int _w, int _n) { u = _u; v = _v; w = _w; nxt = _n; } } int n; int edgecnt; int len1[] = new int [MAX_N]; int len2[] = new int [MAX_N]; int id1[] = new int [MAX_N]; int id2[] = new int [MAX_N]; int head[] = new int [MAX_N]; Edge E[] = new Edge[MAX_N << 1]; void add(int u, int v, int w) { E[edgecnt] = new Edge(u, v, w, head[u]); head[u] =edgecnt++; } void Clear() { edgecnt = 0; Arrays.fill(head, -1); Arrays.fill(len1, 0); Arrays.fill(len2, 0); Arrays.fill(id1, 0); Arrays.fill(id2, 0); } void swap(int u) { int now = len2[u]; len2[u] = len1[u]; len1[u] = now; now = id2[u]; id2[u] = id1[u]; id1[u] = now; } void dfs(int u, int fa) { for (int i = head[u]; i + 1 != 0; i = E[i].nxt) { int v = E[i].v; if (v == fa) continue; dfs(v, u); if (E[i].w + len1[v] > len2[u]) { len2[u] = len1[v] + E[i].w; id2[u] = v; if (len2[u] > len1[u]) swap(u); } } } void Dfs(int u, int fa) { for (int i = head[u]; i + 1 != 0; i = E[i].nxt) { int v = E[i].v; if (v == fa) continue; if (v == id1[u]) { if (E[i].w + len2[u] > len2[v]) { len2[v] = len2[u] + E[i].w; id2[v] = u; if (len2[v] > len1[v]) swap(v); } } else { if (E[i].w + len1[u] > len2[v]) { len2[v] = len1[u] + E[i].w; id2[v] = u; if (len2[v] > len1[v]) swap(v); } } Dfs(v, u); } } void run() throws IOException { while (cin.hasNext()) { n = cin.nextInt(); Clear(); for (int i = 2; i <= n; ++i) { int v = cin.nextInt(); int w = cin.nextInt(); add(i, v, w); add(v, i, w); } dfs(1, -1); Dfs(1, -1); for (int i = 1; i <= n; ++i) out.println(len1[i]); } out.close(); } public static void main(String[] args) throws IOException { new Main().run(); } Main() { //cin = new InputReader(System.in); cin = new Scanner(System.in); out = new PrintWriter(System.out); } PrintWriter out; // InputReader cin; Scanner cin; class InputReader { InputReader(InputStream in) { reader = new BufferedReader(new InputStreamReader(in)); // try { // reader = new BufferedReader(new FileReader("input.txt")); // } catch (FileNotFoundException ex) { // } 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; } }