Time Limit: 2000MS | Memory Limit: 10000K | |
Total Submissions: 6703 | Accepted: 3090 |
Description
Your program should find the minimum number of soldiers that Bob has to put for a given tree.
For example for the tree:
![](https://i-blog.csdnimg.cn/blog_migrate/43f52b994a402a64db401be44050adc4.jpeg)
the solution is one soldier ( at the node 1).
Input
- the number of nodes
- the description of each node in the following format
node_identifier:(number_of_roads) node_identifier1 node_identifier2 ... node_identifiernumber_of_roads
or
node_identifier:(0)
The node identifiers are integer numbers between 0 and n-1, for n nodes (0 < n <= 1500);the number_of_roads in each line of input will no more than 10. Every edge appears only once in the input data.
Output
Sample Input
4
0:(1) 1
1:(2) 2 3
2:(0)
3:(0)
5
3:(3) 1 4 2
1:(1) 0
2:(0)
0:(0)
4:(0)
dp[u][1]+=min(dp[v][0],dp[v][1]);
dp[u][0]+=dp[v][1];
#include<cstdio>
#include<iostream>
#include<string.h>
using namespace std;
#define MAXN 1501
int pre[MAXN],Child[MAXN],root,n,dp[MAXN][2];
void DP(int root)
{
int dp0=0,dp1=0;
if(Child[root]==0){ //叶子节点
dp[root][1]=1;
dp[root][0]=0;
return;
}
for(int i=0;i<n;i++){
if(pre[i]==root){
DP(i);
dp0 += dp[i][1];
dp1 += min(dp[i][1],dp[i][0]);
}
}
dp[root][0] =dp0;
dp[root][1] =dp1+1;
}
int main()
{
int i,father,m,child;
while(~scanf("%d",&n)){
memset(dp,0,sizeof(dp));
memset(pre,-1,sizeof(pre));
root=-1;
memset(Child,-1,sizeof(Child));
for(int i=0;i<n;i++){
scanf("%d:(%d)",&father,&m);
Child[father]=m;
if(root==-1)root=father;
while(m--){
scanf("%d",&child);
pre[child]=father;
if(child==root)root=father;
}
}
DP(root);
printf("%d\n",min(dp[root][1],dp[root][0]));
}
return 0;
}