传送门:牛客
题目描述:
Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the
solution fast enough and then he is very sad. Now he has the following problem. He must defend a
medieval city, the roads of which form a tree. He has to put the minimum number of soldiers on the
nodes so that they can observe all the edges. Can you help him?
Your program should find the minimum number of soldiers that Bob has to put for a given tree.
For example for the tree:
the solution is one soldier ( at the node 1).
输入:
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)
输出:
1
2
经典的树形dp的题目
主要思路:
然后这道题就巧妙的解决了
下面是具体的代码部分:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
#define root 1,n,1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
inline ll read() {
ll x=0,w=1;char ch=getchar();
for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') w=-1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
return x*w;
}
#define maxn 1000000
#define ll_maxn 0x3f3f3f3f3f3f3f3f
const double eps=1e-8;
int n;int dp[maxn][4];
vector<int>edge[maxn];
void dfs(int u,int pre_u) {
dp[u][0]=1;
for(int i=0;i<edge[u].size();i++) {
int v=edge[u][i];
if(v==pre_u) continue;
dfs(v,u);
dp[u][0]+=min(dp[v][0],dp[v][1]);
dp[u][1]+=dp[v][0];
}
return ;
}
int main() {
while(scanf("%d",&n)!=EOF) {
memset(dp,0,sizeof(dp));
for(int i=0;i<=n;i++) edge[i].clear();
int u,v,num;
for(int i=1;i<=n;i++) {
scanf("%d:(%d)",&u,&num);
for(int j=1;j<=num;j++) {
v=read();
edge[u].push_back(v);
edge[v].push_back(u);
}
}
dfs(0,-1);
cout<<min(dp[0][1],dp[0][0])<<endl;
}
return 0;
}