BZOJ 1517 [POI2006]Met
来源:互联网 发布:阿里巴巴斑马网络 编辑:程序博客网 时间:2024/06/06 10:54
title: ‘BZOJ 1517 [POI2006]Met’
categories: BZOJ
date: 2015-10-21 16:54:00
tags: [贪心,拓扑排序]
Description
给出一棵N个结点的树,选择L条路径,覆盖这些路径上的结点,使得被覆盖到的结点数最多。
Input
第一行两个正整数N、L(2 <= N <= 1,000,000, 0 <= L <= N)。下面有N-1行,每行两个正整数A和B(1 <= A, B <= N),表示一条边(A,B)。
Output
一个整数,表示最多能覆盖到多少结点。
Sample
input.txt
17 3
1 2
3 2
2 4
5 2
5 6
5 8
7 8
9 8
5 10
10 13
13 14
10 12
12 11
15 17
15 16
15 10
output.txt
13
Solution
(试一试刚学到的爆炸读入优化,2333333)
一开始想乱贪,找什么树的直径,然而复杂度挺爆炸的,正确性也不能证明。
于是只能看了一发题解,发现人家说:选择路径的代价相同显然考虑贪心。
很有道理的样子。
我们发现每条路径一定是从一个叶子节点(度为1的节点)到另一个叶子节点,于是叶子节点这一层上面一定会选l对节点,即2*l个节点,而叶子节点上又一定能拓展往它的上一层,于是我们发现,每一层都能选出
然而我发现以前自己拓扑都是用栈打的,所以分出的层不均匀,WA了几万年。什么叫分出的层不均匀?比如在1-2-3-4这条链上,它们的层数会被划分成:1,2,3,1;然而正确的层数应该是:1,2,2,1。于是我们把栈改用队列就可以了,看来以后还是要提高一下自己的姿势水平。
Code
#include<stack>#include<queue>#include<cstdio>#include<cstdarg>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#ifdef __GNUC__#include<unistd.h>#endif#define maxn 1000000+5using namespace std;//#define UsingIOExceptionstatic class Scanner{ typedef double D; typedef unsigned int long II; typedef signed int long SI; typedef unsigned char S; typedef char C; typedef bool B; static II const ScL =16384,Eof =0xff;#ifdef __GNUC__ II const buffer;#else FILE *const buffer;#endif S ram[ScL],*begin,*end;public:#ifdef UsingIOException enum IOException { FileEof,TypeError };#endif#ifdef __GNUC__#ifdef Fin Scanner(II const iobuffer=open(Fin,1)):buffer(iobuffer),begin(ram),end(ram)#else Scanner(II const iobuffer=0):buffer(iobuffer),begin(ram),end(ram)#endif#else#ifdef Fin Scanner(FILE *const iobuffer=fopen(Fin,"rb")):buffer(iobuffer),begin(ram),end(ram)#else Scanner(FILE *const iobuffer=stdin):buffer(iobuffer),begin(ram),end(ram)#endif#endif { } ~Scanner(void) {#ifdef __GNUC__ close(buffer);#else fclose(buffer);#endif } II get(void) { if(begin==end) { begin=ram;#ifdef __GNUC__ if((end=(begin=ram)+read(buffer,ram,ScL))==ram)#else if((end=(begin=ram)+fread(ram,1,ScL,buffer))==ram)#endif return Eof; } return *begin++; } D getSD(void) { II j; while(isspace(j=get())); B neg=false; if(j=='-') { neg=true; j=get(); }#ifdef UsingIOException if(!isdigit(j)) throw j==Eof?FileEof:TypeError;#endif SI i=j-'0'; while(isdigit(j=get())) i=(i<<3)+(i<<1)+(j-'0'); if(j=='.') { D val=D(i),level=1.; while(isdigit(j=get())) val+=(level*=.1)*D(j-'0'); return neg?-val:val; } return neg?-i:i; } D getD(void) { II j; while(isspace(j=get()));#ifdef UsingIOException if(!isdigit(j)) throw j==Eof?FileEof:TypeError;#endif II i=j-'0'; while(isdigit(j=get())) i=(i<<3)+(i<<1)+(j-'0'); if(j=='.') { D val=D(i),level=1.; while(isdigit(j=get())) val+=(level*=.1)*D(j-'0'); return val; } return i; } SI getSI(void) { II j; while(isspace(j=get())); B neg=false; if(j=='-') { neg=true; j=get(); }#ifdef UsingIOException if(!isdigit(j)) throw j==Eof?FileEof:TypeError;#endif SI i=j-'0'; while(isdigit(j=get())) i=(i<<3)+(i<<1)+(j-'0'); return neg?-i:i; } II getII(void) { II j; while(isspace(j=get()));#ifdef UsingIOException if(!isdigit(j)) throw j==Eof?FileEof:TypeError;#endif II i=j-'0'; while(isdigit(j=get())) i=(i<<3)+(i<<1)+(j-'0'); return i; } II getS(void) { II j; while(isspace(j=get()));#ifdef UsingIOException if(!isascii(j)) throw j==Eof?FileEof:TypeError;#endif return j; } C * getCS(C *p) { skip(); while(!isspace(*p++=get())); *--p='\0'; return p; } void skip(int (*const func)(int)=isspace) { while(func(get())); --begin; }}scan;static class Printer{ typedef unsigned int long II; typedef char C; static II const ScL =16384,Ral =100; C self[ScL+Ral],*sp,*const slimit; FILE *const buffer;public:#ifdef Fout Printer(FILE *const iobuffer=fopen(Fout,"wb")):sp(self),slimit(self+ScL),buffer(iobuffer)#else Printer(FILE *const iobuffer=stdout):sp(self),slimit(self+ScL),buffer(iobuffer)#endif { } ~Printer(void) { flush(); fclose(buffer); } void flush(void) { fwrite(self,1,sp-self,buffer); sp=self; } void print(C const *const s,...) { va_list h; va_start(h,s); if((sp+=vsprintf(sp,s,h))>=slimit) flush(); va_end(h); } void puts(C const *const s) { if((sp+=strlen(strcpy(sp,s)))>=slimit) flush(); } void putchar(II const x) { *sp++=(C)x; if(sp>=slimit) flush(); }}sysout;vector <int> a[maxn];queue <int> q;int du[maxn],sum[maxn],dep[maxn];int n,l,ans,cnt;void Toposort(){ for(int i=1;i<=n;i++) if(du[i]==1) q.push(i),dep[i]=1,sum[1]++; while(!s.empty()){ int x=q.front(); q.pop(); int len=a[x].size(); cnt=max(cnt,dep[x]); for(int i=0;i<len;i++) if(du[a[x][i]]!=1){ du[a[x][i]]--; if(du[a[x][i]]==1){ dep[a[x][i]]=dep[x]+1; sum[dep[x]+1]++; q.push(a[x][i]); } } } for(int i=1;i<=cnt;i++) ans+=min(2*l,sum[i]);}int main(){ n=scan.getSI(); l=scan.getSI(); for(int i=1;i<n;i++){ int x,y; x=scan.getSI(); y=scan.getSI(); a[x].push_back(y); a[y].push_back(x); du[x]++; du[y]++; } Toposort(); printf("%d",ans); return 0; }
- BZOJ 1517 [POI2006]Met
- BZOJ 1517 [POI2006]Met 贪心
- bzoj1517: [POI2006]Met
- bzoj 1442: [Poi2006]Crystal
- [bzoj]1520: [POI2006]Szk-Schools
- BZOJ 1442: [Poi2006]Crystal dp
- BZOJ 1510 [POI2006]Kra-The Disks 二分
- BZOJ 1510: [POI2006]Kra-The Disks
- 【BZOJ】【P1510】【POI2006】【Kra-The Disks】【题解】【前缀min+二分】
- 【BZOJ】【P1520】【POI2006】【Szk-Schools】【题解】【费用流】
- BZOJ 1513 POI2006 Tet-Tetris 3D 二维线段树
- BZOJ 1511 [POI2006]OKR-Periods of Words KMP
- BZOJ 1513 [POI2006]Tet-Tetris 3D 二维线段树
- BZOJ 1514 _ [POI2006]ZAB-Frogs 单调队列+二分BFS
- [二维线段树] BZOJ 1513 [POI2006]Tet-Tetris 3D
- bzoj 1511: [POI2006]OKR-Periods of Words (kmp+乱搞)
- bzoj 1512 [POI2006]Pro-Professor Szu tarjan dp
- BZOJ 1513: [POI2006]Tet-Tetris 3D 二维线段树
- eclipse 配置
- YII2 unknown scenarios:default问题原因查找
- 安卓获取图片缩略图的两种方式
- android-----XUtils框架之HttpUtils源码分析
- AsynTask版本兼容问题
- BZOJ 1517 [POI2006]Met
- ViewRootImpl入门
- 如何创建回调,得知iPhone设备的接入和拔出信息
- MFC画刷类CBrush使用实例 .
- java 的引用类型
- 获得网络接口信息和网卡信息
- 44个Javascript变态题解析
- HDU-3193 Find the hotel
- 如何在5个月内做出月入3万的业余项目