UVALive 4015 Caves 树形背包

来源:互联网 发布:屏幕测试软件 编辑:程序博客网 时间:2024/04/29 07:04

题目链接:点击打开链接

题意:

给定n个点的有根树(0为根),

下面给出边和边权

一个整数q表示q个询问

每个询问一个数字x ,表示有一个人从根开始走,行走距离不超过x且使得走过不相同的点最多。

问最多能走多少个点。

思路:

dp[i][j][0]表示以i为根的子树,以i为起点走了j个不同点且回到i的最小花费。

dp[i][j][1]表示不需要回到i的最小花费。

转移的时候就是一个背包


import java.io.PrintWriter;import java.text.DecimalFormat;import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.Comparator;import java.util.HashMap;import java.util.Iterator;import java.util.LinkedList;import java.util.Map;import java.util.PriorityQueue;import java.util.Scanner;import java.util.Stack;import java.util.TreeMap;import java.util.TreeSet;import java.util.Queue;public class Main {int n, q;int[] siz = new int[N];int[][][] dp = new int[N][N][2];//dp[i][j][0]表示以i为子树 走了j个点后回到i的最小花费,1表示不回到iint[][] tmp = new int[N][2];void input(){init_edge();for(int i = 1, u, v, dis; i < n; i++){u = cin.nextInt(); v = cin.nextInt(); dis = cin.nextInt();add(u, v, dis);add(v, u, dis);}q = cin.nextInt();}void dfs(int u, int fa){dp[u][1][0] = dp[u][1][1] = 0;siz[u] = 1;for(int i = head[u]; i != -1; i = edge[i].nex){int v = edge[i].to; if(v == fa)continue;dfs(v, u);siz[u] += siz[v];for(int j = siz[u]; j > 1; j--){for(int k = 1; k <= siz[v] && j-k>=0; k++){dp[u][j][0] = min(dp[u][j][0], dp[u][j-k][0]+dp[v][k][0]+edge[i].dis*2);dp[u][j][1] = min(dp[u][j][1], dp[u][j-k][0]+dp[v][k][1]+edge[i].dis);dp[u][j][1] = min(dp[u][j][1], dp[u][j-k][1]+dp[v][k][0]+edge[i].dis*2);}}}//out.print(u+" back:");for(int i = 1; i <= siz[u]; i++)out.print(dp[u][i][0]+ " "); out.println();out.print(u+" not back:");for(int i = 1; i <= siz[u]; i++)out.print(dp[u][i][1]+ " "); out.println();}void work() {int Cas = 1;while(true){n = cin.nextInt(); if(n == 0)break;input();for(int i = 0; i <= n; i++) for(int j = 0; j <= n; j++)dp[i][j][0] = dp[i][j][1] = inf;dfs(0, 0);out.println("Case "+(Cas++)+":");while(q-->0){int x = cin.nextInt(), ans = 1;for(int i = 2; i <= n; i++)if(x>=dp[0][i][1])ans = i;out.println(ans);}}}Main() {cin = new Scanner(System.in);out = new PrintWriter(System.out);}public static void main(String[] args) {Main e = new Main();e.work();out.close(); }public Scanner cin;public static PrintWriter out;static int N = 505;static int M = 505;DecimalFormat df=new DecimalFormat("0.0000");static int inf = (int) 1e9 + 7;static long inf64 = (long) 1e18;static double eps = 1e-8;static int mod = 1000000007 ;class Edge{int from, to, dis, nex;Edge(){}Edge(int from, int to, int dis, int nex){this.from = from;this.to = to;this.dis = dis;this.nex = nex;}}Edge[] edge = new Edge[M<<1];int[] head = new int[N];int edgenum;void init_edge(){for(int i = 0; i < N; i++)head[i] = -1; edgenum = 0;}void add(int u, int v, int dis){edge[edgenum] = new Edge(u, v, dis, head[u]);head[u] = edgenum++;}/*int upper_bound(int[] A, int l, int r, int val) {// upper_bound(A+l,A+r,val)-A;int pos = r;r--;while (l <= r) {int mid = (l + r) >> 1;if (A[mid] <= val) {l = mid + 1;} else {pos = mid;r = mid - 1;}}return pos;}/**/int Pow(int x, int y) {int ans = 1;while (y > 0) {if ((y & 1) > 0)ans *= x;y >>= 1;x = x * x;}return ans;}double Pow(double x, int y) {double ans = 1;while (y > 0) {if ((y & 1) > 0)ans *= x;y >>= 1;x = x * x;}return ans;}int Pow_Mod(int x, int y, int mod) {int ans = 1;while (y > 0) {if ((y & 1) > 0)ans *= x;ans %= mod;y >>= 1;x = x * x;x %= mod;}return ans;}long Pow(long x, long y) {long ans = 1;while (y > 0) {if ((y & 1) > 0)ans *= x;y >>= 1;x = x * x;}return ans;}long Pow_Mod(long x, long y, long mod) {long ans = 1;while (y > 0) {if ((y & 1) > 0)ans *= x;ans %= mod;y >>= 1;x = x * x;x %= mod;}return ans;}int gcd(int x, int y){if(x>y){int tmp = x; x = y; y = tmp;}while(x>0){y %= x;int tmp = x; x = y; y = tmp;}return y;}int max(int x, int y) {return x > y ? x : y;}int min(int x, int y) {return x < y ? x : y;}double max(double x, double y) {return x > y ? x : y;}double min(double x, double y) {return x < y ? x : y;}long max(long x, long y) {return x > y ? x : y;}long min(long x, long y) {return x < y ? x : y;}int abs(int x) {return x > 0 ? x : -x;}double abs(double x) {return x > 0 ? x : -x;}long abs(long x) {return x > 0 ? x : -x;}boolean zero(double x) {return abs(x) < eps;}}


0 0
原创粉丝点击