Rebuilding Roads
Time Limit: 1000MS |
|
Memory Limit: 30000K |
Total Submissions: 10663 |
|
Accepted: 4891 |
Description
The cows has reconstructed Farmer John's farm, with its N-barns (1 <= n <=, number 1..N) after the terrible ear Thquake. The cows didn ' t has time to rebuild any extra roads, so now there is exactly one-to-get from any given barn to any OT Her barn. Thus, the farm transportation system can be represented as a tree.
Farmer John wants to know what much damage another earthquake could do. He wants to know the minimum number of roads whose destruction would isolate a subtree of exactly P (1 <= P <= N) ba RNs from the rest of the barns.
Input
* Line 1:two integers, N and P
* Lines 2..n:n-1 Lines, each with a integers I and J. Node I is node J's parent in the tree of roads.
Output
A single line containing the integer so is the minimum number of roads so need to being destroyed for a subtree of P node s to be isolated.
Sample Input
11 61 21 31 41 52 62 72 84 94 104 11
Sample Output
2
Hint
[A subtree with nodes (1, 2, 3, 6, 7, 8) would become isolated if roads 1-4 and 1-5 are destroyed.]
Test instructions: The minimum number of cuts required to take m points in a tree with n nodes n-1 edges.
Analysis: Dp[u][i] represents a subtree with the root node of U to get the sub-tree of I nodes requires a minimum number of cuts if you consider the subtree V of U, if we take k points in the Father tree, then take i-k points in the subtree
Dp[u][i] = min (Dp[u][k],dp[v][i-k]) ..... 1
If we do not consider V, then we only need a knife to separate the subtree K from the father can dp[u][i] = dp[u][i]+1; .......... 2
Comprehensive above: dp[u][i] = min (ON)
When we think of u, it is equal to U is a backpack with a capacity of M (m for backpack capacity), a sub-tree with M nodes, each point is only taken or not, so it can be regarded as 01 backpack.
#include <iostream>#include<stdio.h>#include<string.h>#include<stdlib.h>#include<math.h>#include<algorithm>#defineN 155using namespacestd;intHead[n];structedge{intU,v,next;} Edge[n];intIndegree[n];voidAddedge (intUintVint&k) {edge[k].u= U,EDGE[K].V =v; Edge[k].next= head[u],head[u]=k++;}intn,m;intDp[n][n];///Dp[u][i] Represents the subtree with the root node of U as the minimum number of cuts required to get the sub-tree of I nodes///If you consider the subtree V of U, if we take k points in the Father tree, then take i-k points in the subtree///Dp[u][i] = min (dp[u][k],dp[v][i-k])///If we do not consider V, then we only need a knife to separate the subtree K from the father can dp[u][i] = dp[u][i]+1;///comprehensive above: dp[u][i] = min (min (dp[u][k],dp[v][i-k)), dp[u][i]+1)///when we consider u, it is equal to U is a backpack with a capacity of M (m for backpack capacity), and a sub-tree is composed of M nodes, each point is only taken or not taken, so///it can be seen as a 01 backpack .voidDfsintu) { for(intI=0; i<=m;i++) dp[u][i]=999999; dp[u][1]=0;///Initialize only take one point of yourself for(intK = head[u];k!=-1; k=Edge[k].next) { intv =edge[k].v; DFS (v); for(intj=m;j>=1; j--) {///Reverse Enumerationdp[u][j]+=1;///when you do not take the subtree for(intk=1; k<j;k++) {///father on the tree to get some intt = j-k;///the points taken on the sub-treeDp[u][j] = min (dp[u][k]+Dp[v][t],dp[u][j]); } } }}intMain () { while(SCANF ("%d%d", &n,&m)! =EOF) {memset (Indegree,0,sizeof(Indegree)); memset (Head,-1,sizeof(head)); inttot =0; intu,v; for(intI=1; i<n;i++) {scanf ("%d%d",&u,&v); Addedge (U,v,tot); INDEGREE[V]++; } intRoot; for(intI=1; i<=n;i++)if(indegree[i]==0) {root = i; Break;} //printf ("%d\n", root);Dfs (root); intAns =Dp[root][m]; for(intI=1; i<=n;i++) {///plus one because of the father's knot and the side of it. if(dp[i][m]+1<ans) ans = dp[i][m]+1; } printf ("%d\n", ans); } return 0;}
POJ 1947 (tree-shaped dp+01 backpack)