不充钱,你怎么AC?

  题目:http://codevs.cn/problem/1091/

  大家都写的 DFS,然而我想到了一种贪心的做法,重点是可以A

  普遍的贪心是每次删掉该深度子树最大的点,但是如果有一边卡一条链就会WA

  我们何不进一步考虑贪心,如果它下面是一条链我们就可以缓一缓到第 2 天再删是不是,反正它每次也就增加一个人

  用 size[x] 记录所有后代加上自己的节点个数,f[x] 记录其最大子树的 size 值

  我们考虑第一次不删这个节点,让它先扩展一次,然后第二次再删除它子树中 size 最大的节点

  那么设 g[x]=size[x]-f[x],g 就为第一次不删,第二次删掉其最大的子树还剩余的节点数

  一条链的 g[x]=1,而一个多叉节点的 g[x]>1,这就意味着先要删去 g 值更大的那个节点,才能不让它下一次扩展更多的出来

  那么一层层地贪心,每次删掉 g 值最大的节点,直到不再继续传染为止

  贪心跑得飞快~

 #include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<stack>
using namespace std; const int N=;
stack<int> s,q;
int first[N],v[N*],next[N*],size[N],g[N],f[N];
void dfs(int x,int fa)
{
f[x]=fa;
int i;
for (i=first[x];i;i=next[i])
{
if (v[i]==fa) continue;
dfs(v[i],x);
if (size[v[i]]>g[x]) g[x]=size[v[i]];
}
size[fa]+=size[x];
}
int main()
{
int n,m,i,x,ans=;
scanf("%d%d",&n,&m);
for (i=;i<=m;i++)
{
scanf("%d%d",&x,&v[i]);
v[i+m]=x;
next[i]=first[x];
first[x]=i;
next[i+m]=first[v[i]];
first[v[i]]=i+m;
}
for (i=;i<=n;i++) size[i]=;
dfs(,);
for (i=;i<=n;i++) g[i]=size[i]-g[i];
s.push();
g[]=size[]=;
ans=n;
while (!s.empty())
{
m=;
while (!s.empty())
{
x=s.top();
s.pop();
for (i=first[x];i;i=next[i])
{
if (v[i]==f[x]) continue;
if (g[v[i]]>g[m]||(g[v[i]]==g[m]&&size[v[i]]>size[m])) m=v[i];
q.push(v[i]);
}
}
while (!q.empty())
{
x=q.top();
q.pop();
if (x==m) ans-=size[m];
else s.push(x);
}
}
printf("%d\n",ans);
return ;
}

  这里有个DFS的:http://blog.csdn.net/yuyanggo/article/details/48087431

  贪心的做法证明有人会严谨的吗?会的话告诉我谢谢!

[ CodeVS冲杯之路 ] P1091的更多相关文章

  1. [ CodeVS冲杯之路 ] P1368

    不充钱,你怎么AC? 题目:http://codevs.cn/problem/1368/ 嗯……泡泡堂,很劲啊,其实就是个盗版的田忌赛马 http://www.cnblogs.com/hyfer/p/ ...

  2. [ CodeVS冲杯之路 ] P1092

    不充钱,你怎么AC? 题目:http://codevs.cn/problem/1092/ 嗯,这道题有一定难度啊,需要先用扩展欧几里得算法求出逆元,然后按照大小构一颗带边权为小时数的树 树链剖分后在树 ...

  3. [ CodeVS冲杯之路 ] P3955

    不充钱,你怎么AC? 题目:http://codevs.cn/problem/3955/ 最长上升子序列的加强版,n 有1000000,n 方的 DP 肯定会 TLE,那么用二分栈维护 二分栈我讲不好 ...

  4. [ CodeVS冲杯之路 ] P1165

    不充钱,你怎么AC? 题目:http://codevs.cn/problem/1165/ 题目很简单,代码最好写朴实一点,不要想着哪些情况可以合并在一起啊等等 老老实实一个个判断,不然很容易出错 细节 ...

  5. [ CodeVS冲杯之路 ] P1053

    不充钱,你怎么AC? 题目:http://codevs.cn/problem/1053/ 直接扫一遍串,把字母对应的 ascii 码直接做数组下标,交给数组统计 最后查询一遍数组的 'a'-'z' , ...

  6. [ CodeVS冲杯之路 ] P1171

    不充钱,你怎么AC? 题目:http://codevs.cn/problem/1171/ 代码调了很久才调好啊,一开始题目都看错了(要是真的NOIP肯定没戏了QuQ) 后面发现CodeVS上的数据输入 ...

  7. [ CodeVS冲杯之路 ] P1197

    不充钱,你怎么AC? 题目:http://codevs.cn/problem/1197/ 密钥的字母可以全转换为小写字母,然后一一映射,a→0,b→1,c→2,依此类推 对于密文只需将每一位减去对应密 ...

  8. [ CodeVS冲杯之路 ] P2492

    不充钱,你怎么AC? 题目:http://codevs.cn/problem/2492/ 在此先orz小胖子,教我怎么路径压缩链表,那么这样就可以在任意节点跳进链表啦(手动@LCF) 对于查询操作,直 ...

  9. [ CodeVS冲杯之路 ] P2456

    不充钱,你怎么AC? 题目:http://codevs.cn/problem/2456/ 用贪心的思想,木材当然要尽量分成多的木板,而大的木材能够分成大木板,但是小的木材不一定能够分成大的木板,所以木 ...

随机推荐

  1. 指定的参数已超出有效值的范围。 参数名: site

    “/”应用程序中的服务器错误. 指定的参数已超出有效值的范围.参数名: site 说明: 执行当前 Web 请求期间,出现未经处理的异常.请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的 ...

  2. linux 共享内存

    共享内存是最高效的IPC机制,因为它不涉及进程之间的任何数据传输.这种高效带来的问题是,我们必须用其他手段来同步进程对共享内存的访问,否则会产生竞态条件.所以,共享内存通常和其他进程间通信方式一起使用 ...

  3. 裸机——SD卡

    1.首先要对SD卡有个基础知识 (1) SD = nandflash + 主控IC. 主控IC负责了校验和坏块管理,所以SoC只需要依照时序就可以和SD卡上的主控IC进行数据交换等操作. (2) SD ...

  4. 零基础学css第二天

    内边距与外边距: <!DOCTYPE html> <html> <head> <title></title> <style type= ...

  5. aspx页面 按钮不响应回车键

    aspx页面在IE浏览器中,页面上的按钮默认都响应回车键,但有的时候我们的文本框可能需要响应回车键,这时我们就不想让按钮再响应回车键,这时我们只需要设置按钮的属性即可. 按钮分为两种,一种是<b ...

  6. 4 Django简介

    MVC与MTV模型 MVC Web服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的.松耦合的方式连接在一起,模型负责业务 ...

  7. android 布局preview 技巧

    最近开始看老外写的文章,博客,嗯,不能说比国人写的好,但是感觉看着很爽.真的,一手资料就是爽. 嗯,自己做得不错,第一次看外文博客,我知道自己怎么看的,一句话一句话看下来的,越看越有感觉. 下面这个 ...

  8. Java的接口和抽象类深入理解

    对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者确实有很多相似的地方,看了一整天别人怎么说,大致总结如下: 一.抽象类 在了解抽象类 ...

  9. PowerDesigner常用功能总结

    1.PowerDesigner设计表时显示注释列Comment 选中准备编辑的表,[右键]->[Properties]->[Columns]->[Customize Columns ...

  10. 转载——一步步学习js

    一步步学习javascript基础篇(0):开篇索引 阅读目录 索引: 一步步学习javascript基础篇(1):基本概念 一步步学习javascript基础篇(2):作用域和作用域链 一步步学习j ...