博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Luogu4149 [IOI2011]Race
阅读量:6074 次
发布时间:2019-06-20

本文共 2643 字,大约阅读时间需要 8 分钟。

真真正正的淀粉质模板题。

为什么?之前那个O(N^2)检验子树的算法对于菊花图就很呵呵。

这个题,难点在于对子树的统计。

我们无法使用容斥一类的思想。

但是我们可以使用一种其他的方法。

也就是利用其中一颗的子树与其他子树的信息进行统计答案。

这样的话,就可以保证同一个子树内的信息不会被统计多次。

#include 
#include
#include
#include
/*using std::min;using std::max;*/const int N=201000;const int K=1010000;const int inf=0x7ffffff;struct node{ int p; int value; int nxt;};node line[N<<1];int head[N],tail;int size[N],f[N],vis[N];int root,sum,ans;int T[K];int n,k;int max(int a,int b){ return a > b ? a : b ;}int min(int a,int b){ return a < b ? a : b ;}int read(){ int res=0,flag=1; char c=getchar(); while(c>'9'||c<'0') { if(c=='-') flag=-1; c=getchar(); } while(c>='0'&&c<='9') { res=(res<<1)+(res<<3)+c-'0'; c=getchar(); } return res*flag;}void add(int a,int b,int c){ line[++tail].p=b; line[tail].value=c; line[tail].nxt=head[a]; head[a]=tail; return ;}void get_hry(int now,int fa){ size[now]=1;f[now]=0; int v; for(int i=head[now];i;i=line[i].nxt) { v=line[i].p; if(vis[v]||v==fa) continue; get_hry(v,now); f[now]=max(f[now],size[v]); size[now]+=size[v]; } f[now]=max(f[now],sum-size[now]); if(f[root]>f[now]) root=now; return ;}void get_DD(int now,int fa,int Dis,int Dep){ if(Dis>k) return ; ans=min(ans,T[k-Dis]+Dep); int v; for(int i=head[now];i;i=line[i].nxt) { v=line[i].p; if(v==fa||vis[v]) continue; get_DD(v,now,Dis+line[i].value,Dep+1); } return ;}void updata(int now,int fa,int Dis,int Dep,int model){ if(Dis>k) return ; if(model) T[Dis]=min(T[Dis],Dep); else T[Dis]=inf; int v; for(int i=head[now];i;i=line[i].nxt) { v=line[i].p; if(v==fa||vis[v]) continue; updata(v,now,Dis+line[i].value,Dep+1,model); } return ;}void solve(int now){ vis[now]=1; T[0]=0; int v; for(int i=head[now];i;i=line[i].nxt) { v=line[i].p; if(vis[v]) continue; get_DD(v,now,line[i].value,1); //ADD(); updata(v,now,line[i].value,1,1);; } for(int i=head[now];i;i=line[i].nxt) { v=line[i].p; if(vis[v]) continue; updata(v,now,line[i].value,1,0); } for(int i=head[now];i;i=line[i].nxt) { v=line[i].p; if(vis[v]) continue; sum=size[v];root=0; get_hry(v,now); solve(root); } return ;}int main(){ //scanf("%d%d",&n,&k); n=read(),k=read(); for(int i=1;i<=k;i++) T[i]=inf; for(int i=1,a,b,c;i

转载于:https://www.cnblogs.com/Lance1ot/p/10293310.html

你可能感兴趣的文章
[软件推荐]jQuery,JavaScript,HTML,CSS,PHP,MySQL,正则表达式 CHM帮助手册
查看>>
Java打war包、jar包
查看>>
Blend 3状态为空的解决方法
查看>>
LeetCode My Solution: Minimum Depth of Binary Tree
查看>>
Silverlight实用窍门系列:57.Silverlight中的Binding使用(二)-数据验证
查看>>
破万。
查看>>
Spark SQL概念学习系列之如何使用 Spark SQL(六)
查看>>
Linux VFS中write系统调用实现原理【转】
查看>>
LocalReport Print with C# C#打印RDLC
查看>>
Android -- 获取汉字的首字母
查看>>
最大长方形 (Maximum Submatrix & Largest Rectangle)(涵盖各种求最大矩形题目)
查看>>
C#设置窗体打开位置(在显示器的右下角打开)
查看>>
网易邮箱繁体字信件乱码解决
查看>>
大叔也说Xamarin~Android篇~调用远程API接口,发POST请求
查看>>
ASP.NET配置错误页面浅析
查看>>
OAuth2授权原理
查看>>
如何在一个程序集中序列化在另一个中反序列化
查看>>
基于.NET打造IP智能网络视频监控系统
查看>>
利用python做数据分析 札记(一)
查看>>
【C#代码实战】群蚁算法理论与实践全攻略——旅行商等路径优化问题的新方法...
查看>>