感动啊 瞎弄了那么久之后一A 还发现是最快的(后面的人手下留情啊) 实在是开心。。
这道题挺好的,网上还没人写题解?(貌似是有些博客园不能被搜出来吧)
进入正题,其实我也不知道应该怎么讲
首先 你应该随便画些树出来自己玩一下,这里我就提供一个吧(当然你应该玩多几个)
玩一下之后再来看下面的。。
然后我们来讲一下怎么样总结出怎么搞
不难发现 求最大值和最小值都是最优能取到第几大和第几小
所以其实讨论起来可以讨论为 当前决策者的目的 和 答案所求的目的是否一样
当前层一样 下一层则不一样 反之亦然
- 一样的时候就是下一层不一样的取min
- 不一样的时候就是下一层一样的加起来
显然叶子节点的两个值是一样的 从下往上搞一波就好了
#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;
}