n个结点的树,求最少删除多少条边:使得构成的森林中有一个树的结点个数恰好为P。
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) {
new Task().sovle();
}
}
class Task {
InputReader in = new InputReader(System.in);
PrintWriter out = new PrintWriter(System.out);
void sovle() {
int n = in.nextInt() ;
p = in.nextInt() ;
adj = new List[n+1] ;
dp = new int[n+1][n+1] ;
hasFather = new boolean[n+1] ;
Arrays.fill(hasFather , false) ;
for(int i = 1 ; i <= n ; i++){
Arrays.fill(dp[i] , inf) ;
adj[i] = new ArrayList<Integer>() ;
}
for(int i = 1 ; i < n ; i++){
int u = in.nextInt() ;
int v = in.nextInt() ;
adj[u].add(v) ;
hasFather[v] = true ;
}
int root = 1 ;
for(int i = 1 ; i <= n ; i++){
if(! hasFather[i]){
root = i ;
break ;
}
}
dfs(root) ;
int res = dp[root][p] ;
for(int i = 1 ; i <= n ; i++){
if(i == root) continue ;
res = Math.min(res , dp[i][p] + 1) ;
}
out.println(res) ;
out.flush() ;
}
final int inf = 1000000000 ;
List<Integer>[] adj ;
int dp[][] ;
int p ;
boolean[] hasFather ;
void dfs(int u){
if(adj[u] == null) return ;
for(int v : adj[u]){
dfs(v) ;
}
dp[u][1] = adj[u].size() ;
for(int v : adj[u]){
for(int i = p ; i >= 1 ; i--){
for(int j = 1 ; i+j <= p ; j++){
dp[u][i+j] = Math.min(dp[u][i] + dp[v][j] - 1 , dp[u][i+j]) ;
}
}
}
}
}
class InputReader {
public BufferedReader reader;
public StringTokenizer tokenizer;
public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = new StringTokenizer("");
}
private void eat(String s) {
tokenizer = new StringTokenizer(s);
}
public String nextLine() {
try {
return reader.readLine();
} catch (Exception e) {
return null;
}
}
public boolean hasNext() {
while (!tokenizer.hasMoreTokens()) {
String s = nextLine();
if (s == null)
return false;
eat(s);
}
return true;
}
public String next() {
hasNext();
return tokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
public double nextDouble() {
return Double.parseDouble(next());
}
public BigInteger nextBigInteger() {
return new BigInteger(next());
}
}