luogu P1922 女仆咖啡厅桌游吧

题目背景

小v带萌萌的妹妹去玩,妹妹想去女仆咖啡馆,小v想去桌游吧。

妹妹:“我问你个问题,答不对你就做我一天的奴隶,答对了就今天我就全部听你的。”

小v:“全部都听!?”

妹妹:“嘻嘻嘻,你还是回答问题吧!”

于是小v为了自己一天的幸福,来向你求助。

题目描述

小v所在的世界被规划成了树形结构,每一个节点上都可以建一个女仆咖啡厅或者桌游吧或者什么都不建。在确定点1为根节点之后,规划局要求:对于每一个非叶子的节点i,设它子树(包括自己)中所有的女仆咖啡厅的数量为cafe[i],桌游吧数目为table[i],都有cafe[i]等于table[i]。

妹妹的问题是:这颗树最多能放多少个女仆咖啡厅。

输入输出格式

输入格式:

第一行,一个正整数N

第二至N行,每行两个正整数ui,vi,表示vi,ui有一条边。

输出格式:

只有一行,最多能放的女仆咖啡厅的个数。

输入输出样例

输入样例#1: 复制
5
1 2
2 3
3 4
2 5
输出样例#1: 复制
2

说明

对于30%的数据,1<=N<=20

对于100%的数据,1<=N<=10^5

 对于完全符合子树的贡献是节点数/2,对于其父节点的贡献是他的贡献与单个空节点贡献

#include<cstdio>
#include<algorithm>
const int maxn = 1e6+7; 
inline int read() {
    int x=0,f=1;
    char c=getchar() ;
    while(c<'0'||c>'9'){ if(c=='-')f=-1;c=getchar();};
    while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar();
    return x*f;
}
int n;
struct node{
    int v,next;
}edge[maxn];
int head[maxn],num;
void add_edge(int x,int y) {
    edge[++num].v=y,edge[num].next=head[x],head[x]=num;
}
int dp[maxn];
void dfs(int x,int f) {
    int tmp=1;dp[x]=0;
    for(int i=head[x];i;i=edge[i].next) {
        int v=edge[i].v;
        if(v==f)continue;
        dfs(v,x);
        if(!dp[v]) tmp++;
        else dp[x]+=dp[v];
    }
    tmp/=2;
    dp[x]+=tmp;
}
int main() {
    n=read();
    for(int a,b,i=1;i<n;++i) {
        a=read(),b=read();
        add_edge(a,b);
        add_edge(b,a);
    }
    dfs(1,1);
    printf("%d
",dp[1]);
}
原文地址:https://www.cnblogs.com/sssy/p/7953262.html