11package class183 ;
22
33// 权值和为k的路径的最少边数,java版
4+ // 一共有n个节点,给定n-1条边,每条边有边权,所有节点组成一棵树
5+ // 给定数字k,要求路径权值和等于k,并且边的数量最小
6+ // 打印最小边数,如果不存在路径打印-1,注意点的编号从0开始
7+ // 1 <= n <= 2 * 10^5
8+ // 0 <= 边权、k <= 10^6
49// 测试链接 : https://www.luogu.com.cn/problem/P4149
510// 提交以下的code,提交时请把类名改成"Main",可以通过所有测试用例
611
@@ -29,20 +34,20 @@ public class Code02_Race1 {
2934 public static int total ;
3035 public static int centroid ;
3136
32- public static int [] sumArr = new int [MAXN ];
37+ public static int [] disArr = new int [MAXN ];
3338 public static int [] edgeArr = new int [MAXN ];
3439 public static int cnta ;
3540
3641 public static int [] dp = new int [MAXK ];
3742
3843 // 讲解118,递归函数改成迭代所需要的栈
3944 public static int [][] stack = new int [MAXN ][5 ];
40- public static int stacksize , u , f , sum , edge , e ;
45+ public static int stacksize , u , f , dis , edge , e ;
4146
42- public static void push (int u , int f , int sum , int edge , int e ) {
47+ public static void push (int u , int f , int dis , int edge , int e ) {
4348 stack [stacksize ][0 ] = u ;
4449 stack [stacksize ][1 ] = f ;
45- stack [stacksize ][2 ] = sum ;
50+ stack [stacksize ][2 ] = dis ;
4651 stack [stacksize ][3 ] = edge ;
4752 stack [stacksize ][4 ] = e ;
4853 stacksize ++;
@@ -52,7 +57,7 @@ public static void pop() {
5257 --stacksize ;
5358 u = stack [stacksize ][0 ];
5459 f = stack [stacksize ][1 ];
55- sum = stack [stacksize ][2 ];
60+ dis = stack [stacksize ][2 ];
5661 edge = stack [stacksize ][3 ];
5762 e = stack [stacksize ][4 ];
5863 }
@@ -118,41 +123,41 @@ public static void getCentroid2(int cur, int fa) {
118123 }
119124
120125 // 收集信息递归版,java会爆栈,C++可以通过
121- public static void dfs1 (int u , int fa , int sum , int edge ) {
122- if (sum > k ) {
126+ public static void dfs1 (int u , int fa , int dis , int edge ) {
127+ if (dis > k ) {
123128 return ;
124129 }
125- sumArr [++cnta ] = sum ;
130+ disArr [++cnta ] = dis ;
126131 edgeArr [cnta ] = edge ;
127132 for (int e = head [u ]; e > 0 ; e = nxt [e ]) {
128133 int v = to [e ];
129134 if (v != fa && !vis [v ]) {
130- dfs1 (v , u , sum + weight [e ], edge + 1 );
135+ dfs1 (v , u , dis + weight [e ], edge + 1 );
131136 }
132137 }
133138 }
134139
135140 // 收集信息的迭代版
136- public static void dfs2 (int cur , int fa , int psum , int pedge ) {
141+ public static void dfs2 (int cur , int fa , int pathDis , int pathEdge ) {
137142 stacksize = 0 ;
138- push (cur , fa , psum , pedge , -1 );
143+ push (cur , fa , pathDis , pathEdge , -1 );
139144 while (stacksize > 0 ) {
140145 pop ();
141146 if (e == -1 ) {
142- if (sum > k ) {
147+ if (dis > k ) {
143148 continue ;
144149 }
145- sumArr [++cnta ] = sum ;
150+ disArr [++cnta ] = dis ;
146151 edgeArr [cnta ] = edge ;
147152 e = head [u ];
148153 } else {
149154 e = nxt [e ];
150155 }
151156 if (e != 0 ) {
152- push (u , f , sum , edge , e );
157+ push (u , f , dis , edge , e );
153158 int v = to [e ];
154159 if (v != f && !vis [v ]) {
155- push (to [e ], u , sum + weight [e ], edge + 1 , -1 );
160+ push (to [e ], u , dis + weight [e ], edge + 1 , -1 );
156161 }
157162 }
158163 }
@@ -169,15 +174,15 @@ public static int calc(int u) {
169174 // dfs1(v, u, weight[e], 1);
170175 dfs2 (v , u , weight [e ], 1 );
171176 for (int i = tmp + 1 ; i <= cnta ; i ++) {
172- ans = Math .min (ans , dp [k - sumArr [i ]] + edgeArr [i ]);
177+ ans = Math .min (ans , dp [k - disArr [i ]] + edgeArr [i ]);
173178 }
174179 for (int i = tmp + 1 ; i <= cnta ; i ++) {
175- dp [sumArr [i ]] = Math .min (dp [sumArr [i ]], edgeArr [i ]);
180+ dp [disArr [i ]] = Math .min (dp [disArr [i ]], edgeArr [i ]);
176181 }
177182 }
178183 }
179184 for (int i = 1 ; i <= cnta ; i ++) {
180- dp [sumArr [i ]] = INF ;
185+ dp [disArr [i ]] = INF ;
181186 }
182187 return ans ;
183188 }
0 commit comments