bzoj2067: [Poi2004]SZN

一开始没看出来是贪心,还以为是树规,多亏ooo提醒一句,然后刚了一个半小时搞出来了。

首先‘最长线最短’二分没错了,想了想他确实是单调的,最长线越长,用的线就越短(注意这里的最长线只是不超过,并不是一定要达到)。

二分最长线长度,对于已知的最长线长度len,考虑如何求解最少线数。

树里有什么特殊的点吗?叶子节点,叶子节点一定是一条线的一个端点。所以从叶子节点开始,一条线最优肯定是直接连接两个叶子节点,证明自己YY(其实是我不会)。

设f[i]表示节点i向上的线的长度。显然叶子节点的f为1。对于非叶子节点考虑如何合并:

f相加<=len的两个儿子可以合并,但并不是随便合并就是最优的。可以将儿子存到一个队列里,按f值从小到大排序,用两个指针实现合并。如果f[head]+f[tail]<=len直接合并head++,tail--,ans++。如果大于len直接把tail独立成一条线吗?这样并不是最优的,可以把tail的值记录加到f[x]到上一层合并。但是只能有一个点和x接上,显然选f最小的,其他的点就只能独立成一条线了。注意最后如果head==tail要特判是和x接上还是独立成一条线。

这样直接合并到根就求出了最长线长度为len时的最少线数。

复杂度我不会算,有点玄但是跑的还挺快。

  1 //19.00~20.00 :93
  2 //20.00~20.25 :100
  3 #include<algorithm>
  4 #include<iostream>
  5 #include<cstring>
  6 #include<cstdio>
  7 #define int LL
  8 #define MAXN 20010
  9 #define LL long long
 10 #define ma(x) memset(x,0,sizeof(x))
 11 using namespace std;
 12 struct edge
 13 {
 14     int u,v,nxt;
 15     #define u(x) ed[x].u
 16     #define v(x) ed[x].v
 17     #define n(x) ed[x].nxt
 18 }ed[MAXN*4];
 19 int first[MAXN],num_e;
 20 #define f(x) first[x]
 21 const int INF=0x7ffffffffff;
 22 int n,tans;
 23 int f[MAXN];
 24
 25 pair<int,int> q[MAXN];int head,tail;
 26 void dfs(int x,int fa,int len)
 27 {
 28     int tem=0;
 29     for(int i=f(x);i;i=n(i))
 30     if(v(i)!=fa){dfs(v(i),x,len);}
 31
 32     f[x]=0;if(x!=1)f[x]++;head=1,tail=0;int ooo=INF;
 33     for(int i=f(x);i;i=n(i))
 34     if(v(i)!=fa)
 35         if(f[v(i)]==len)tans++;
 36         else{q[++tail]=make_pair(f[v(i)],v(i));}
 37     sort(q+head,q+tail+1);
 38     while(head<tail)
 39     {
 40         if(q[head].first+q[tail].first>len)
 41         {
 42             if(q[tail].first<ooo)
 43             {
 44                 if(ooo!=INF)tans++;
 45                 ooo=q[tail].first;tail--;
 46             }
 47             else tans++,tail--;
 48         }
 49         else head++,tail--,tans++;
 50     }
 51     if(head==tail)
 52     {
 53         if(q[tail].first<ooo)
 54         {
 55             if(ooo!=INF)tans++;
 56             ooo=q[tail].first;
 57         }
 58         else tans++;
 59     }
 60     if(ooo!=INF)f[x]+=ooo;
 61 }
 62 int solve(int len)
 63 {
 64     ma(f);tans=0;
 65     dfs(1,0,len);
 66     if(f[1])tans++;
 67     return tans;
 68 }
 69 inline int read();
 70 inline void add(int u,int v);
 71 signed main()
 72 {
 73 //    freopen("in.txt","r",stdin);
 74     //freopen("1.out","w",stdout);
 75
 76     n=read();int ta,tb;
 77     for(int i=1;i<n;i++)
 78         ta=read(),tb=read(),
 79         add(ta,tb),add(tb,ta);
 80     int l=1,r=n,mid,ans=solve(n),now=INF;
 81     int ans1,ans2;
 82     while(l<=r)
 83     {
 84         mid=(l+r)>>1;
 85         int res=solve(mid);
 86         if(res>ans)l=mid+1;
 87         else
 88         {
 89             r=mid-1,ans=res;
 90             ans1=mid;ans2=res;
 91         }
 92     }
 93     printf("%lld %lld\n",ans2,ans1);
 94 }
 95 inline int read()
 96 {
 97     int s=0,f=1;char a=getchar();
 98     while(a<'0'||a>'9'){if(a=='-')f=-1;a=getchar();}
 99     while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
100     return s*f;
101 }
102 inline void add(int u,int v)
103 {
104     ++num_e;
105     u(num_e)=u;
106     v(num_e)=v;
107     n(num_e)=f(u);
108     f(u)=num_e;
109 }

View Code

转载于:https://www.cnblogs.com/Al-Ca/p/11336869.html

bzoj2067: [Poi2004]SZN相关推荐

  1. 退役前的做题记录1.0

    退役前的做题记录1.0 租酥雨最近很懒qwq,具体表现在写题的时候不想发题解了. 但是想想这样也不太好,就决定发个一句话(半句话到几句话不等)题解上来. 2018-09.18-2018-09.28 [ ...

  2. NOIP2018提高组比赛总结

    NOIP2018提高组比赛总结 前言 新赛季,依旧有很多失误. 在些许的遗憾和无奈中,NOIP2018,撒花结束 纵观今年的整一场NOIP,有许多值得总结的地方 正文 NOIP2018初赛 第二次参加 ...

  3. Noip前的大抱佛脚----赛前任务

    赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...

  4. BZOJ 2073: [POI2004]PRZ( 状压dp )

    早上这道题没调完就去玩NOI网络同步赛了.... 状压dp , dp( s ) 表示 s 状态下所用的最短时间 , 转移就直接暴力枚举子集 . 可以先预处理出每个状态下的重量和时间的信息 . 复杂度是 ...

  5. 【BZOJ2073】[POI2004]PRZ 状压DP

    [BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ...

  6. 2069: [POI2004]ZAW

    2069: [POI2004]ZAW 链接 题意: 给定一张带权图(边是双向的,但不同方向长度不同).求从1出发,至少经过除1外的一个点,再回到1的最短路.点和边不能重复经过. n≤5000,m≤10 ...

  7. [BZOJ2069][POI2004]ZAW

    BZOJ2069 描述 在Byte山的山脚下有一个洞穴入口. 这个洞穴由复杂的洞室经过隧道连接构成. 洞穴的入口是一条笔直通向"前面洞口"的道路. 隧道互相都不交叉(他们只在洞室相 ...

  8. 【POI2004】【Bzoj2069】T2 洞穴 zaw

    T2 洞穴zaw [问题描述] 在 Byte 山的山脚下有一个洞穴入口. 这个洞穴由复杂的洞室经过隧道连接构成. 洞穴的入口是 1 号点.两个洞室要么就通过隧道连接起来,要么就经过若干隧道间接的相连. ...

  9. Bzoj 2073 [POI2004]PRZ

    2073: [POI2004]PRZ Time Limit: 10 Sec  Memory Limit: 64 MB Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们 ...

最新文章

  1. 名图怎么弄云服务器_云服务器购买了宽带的速度怎么测试?
  2. eureka的惊群效应
  3. 项目工作展望(风来)
  4. JAVA中流水账的实现_流水账式java基础Summary
  5. Spark MLlib学习
  6. jqueryd登录异步请求 java,ajaxd的js和jquery实现
  7. 信息学奥赛一本通(2040:【例5.7】筛选法找质数)
  8. u盘弹出工具_mac怎么格式化u盘?
  9. mysql迁移、备份数据表,导出表数据与结构
  10. 《那些年啊,那些事——一个程序员的奋斗史》——65
  11. redis配置文件参数说明及命令操作
  12. [nlp] 双三次插值(BiCubic插值)
  13. M3U8视频解密下载
  14. STEAM上的一款电路模拟神器 — CRUMB Circuit Simulator
  15. 如何判断Map中的key或value是什么类型
  16. 阻容感基础10:电感器分类(4)-变压器
  17. Android LruCache和DiskLruCache相结合打造图片加载框架(仿微信图片选择,照片墙)
  18. Junit 实例精讲基础教程(一) 使用@Ignore注解跳过单元测试方法的执行
  19. JAVA计算机毕业设计橱柜定制系统Mybatis+系统+数据库+调试部署
  20. html img和背景图处理图片不拉伸_img固定宽度和高度,不规则图片变形问题的解决方法...

热门文章

  1. WebService中使用自定义类的解决方法(5种)
  2. 如何对付“新垃圾邮件”?
  3. DataGridView的DataGridViewComboBoxColumn列点击一次,自动处于编辑状态
  4. 图像解码之一——使用libjpeg解码jpeg图片
  5. PyCharm无法启动的问题
  6. 在matlab中如何使用SVM工具箱
  7. 【精华】Linux用户Hive权限控制实践
  8. Leetcode 103. 二叉树的锯齿形层次遍历 解题思路及C++实现
  9. Pandas简明教程:九、表的合并、连接、拼接(数据聚合基础)
  10. 中专学校的计算机教什么,中专计算机学校