BZOJ 4169: Lmc的游戏

25 篇文章 0 订阅
16 篇文章 1 订阅

感动啊 瞎弄了那么久之后一A 还发现是最快的(后面的人手下留情啊) 实在是开心。。
这道题挺好的,网上还没人写题解?(貌似是有些博客园不能被搜出来吧)

进入正题,其实我也不知道应该怎么讲
首先 你应该随便画些树出来自己玩一下,这里我就提供一个吧(当然你应该玩多几个)
这里写图片描述
玩一下之后再来看下面的。。

然后我们来讲一下怎么样总结出怎么搞
不难发现 求最大值和最小值都是最优能取到第几大和第几小
所以其实讨论起来可以讨论为 当前决策者的目的 和 答案所求的目的是否一样
当前层一样 下一层则不一样 反之亦然

  1. 一样的时候就是下一层不一样的取min
  2. 不一样的时候就是下一层一样的加起来
    显然叶子节点的两个值是一样的 从下往上搞一波就好了
#include<bits/stdc++.h>
using namespace std;
const int N=200005,inf=1e9+7;
inline int read(){
    char ch=getchar(); int x=0,f=1;
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0'; ch=getchar();}
    return x*f;
}
struct node{int y,nex;}a[N];
int n,len,first[N];
bool in[N];
void ins(int x,int y){
    a[++len]=(node){y,first[x]},first[x]=len,in[y]=1;
}
int f[N][2],s;
void dfs(int x){
    if(!first[x]){s++,f[x][0]=f[x][1]=1; return;}
    f[x][0]=0,f[x][1]=inf;
    for(int k=first[x];k;k=a[k].nex){
        int y=a[k].y;
        dfs(y);
        f[x][1]=min(f[x][1],f[y][0]);
        f[x][0]+=f[y][1];
    }
}
int main()
{
    n=read();
    for(int i=1;i<n;++i){
        int x=read(),y=read(); ins(x,y);
    }
    int rt; for(int i=1;i<=n;++i)if(!in[i]){rt=i; break;}
    s=0; dfs(rt);
    printf("%d %d\n",s-f[rt][1]+1,f[rt][0]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值