bzoj 3611: [Heoi2014]大工程 && bzoj 2286: [Sdoi2011消耗战
放波建虚树的模板。
大概是用一个栈维护根节点到当前关键点的一条链,把其他深度大于lca的都弹出去。
每次做完记得复原。
还有sort的时候一定要加cmp!!!
bzoj 3611
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 1000005
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
inline int read()
{
int p=;char c=getchar();
while(c<''||c>'')c=getchar();
while(c>=''&&c<='')p=p*+c-'',c=getchar();
return p;
}
int n;
int dfn[N];
int fa[N][];
int dep[N],z;
int head[N],ver[N*],nxt[N*],tot;
void add(int a,int b)
{
tot++;nxt[tot]=head[a];head[a]=tot;ver[tot]=b;
}
void dfs(int x,int f)
{
dfn[x]=++z;
for(int i=head[x];i;i=nxt[i])
{
if(ver[i]==f)continue;
dep[ver[i]]=dep[x]+;
fa[ver[i]][]=x;
dfs(ver[i],x);
}
return ;
}
void lca()
{
for(int i=;i<=;i++)
{
for(int j=;j<=n;j++)
{
fa[j][i]=fa[fa[j][i-]][i-];
}
}return ;
}
int lca(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);
for(int i=;i>=;i--)if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
if(x==y)return x;
for(int i=;i>=;i--)
{
if(fa[x][i]!=fa[y][i])
{
x=fa[x][i];y=fa[y][i];
}
}
return fa[x][];
}
bool cmp(int x,int y)
{
return dfn[x]<dfn[y];
}
int now[N],cnt;
int st[N],top;
int dian[N],num;
int vis[N];
void build()
{
tot=;
st[]=;top=;
for(int i=;i<=cnt;i++)
{
if(now[i]==)continue;
int v=now[i];
int la=lca(st[top],v);
if(st[top]!=la)
{
while(top>=&&dep[st[top-]]>dep[la])
{
add(st[top-],st[top]);top--;
}
add(la,st[top]);top--;
if(st[top]!=la)st[++top]=la;
}
st[++top]=v;
}
while(top>=)add(st[top-],st[top]),top--;
}
ll ans1;
int ans2,ans3;
int size[N];
int mx1[N],mx2[N],mn1[N],mn2[N];
void dfs(int x)
{
dian[++num]=x;
if(vis[x])size[x]=;
else size[x]=;
mx1[x]=mx2[x]=;
mn1[x]=mn2[x]=inf;
for(int i=head[x];i;i=nxt[i])
{
int quan=dep[ver[i]]-dep[x];
dfs(ver[i]);
if(vis[ver[i]])mn1[ver[i]]=;
if(mn1[ver[i]]+quan<mn1[x])
{
mn2[x]=mn1[x];
mn1[x]=mn1[ver[i]]+quan;
}
else if(mn1[ver[i]]+quan<mn2[x])mn2[x]=mn1[ver[i]]+quan;
ans1+=(long long)size[ver[i]]*(cnt-size[ver[i]])*quan;
size[x]+=size[ver[i]];
if(mx1[ver[i]]+quan>mx1[x])
{
mx2[x]=mx1[x];
mx1[x]=mx1[ver[i]]+quan;
}
else if(mx1[ver[i]]+quan>mx2[x])mx2[x]=mx1[ver[i]]+quan;
}
if(vis[x])ans2=min(ans2,mn1[x]);
else ans2=min(ans2,mn1[x]+mn2[x]);
if(mx2[x])ans3=max(ans3,mx1[x]+mx2[x]);
else if(vis[x])ans3=max(ans3,mx1[x]);
}
int main()
{
n=read();
int t1,t2,t3,t4;
for(int i=;i<n;i++)
{
t1=read();t2=read();
add(t1,t2);add(t2,t1);
}
dep[]=;
dfs(,-);
lca();
int q,k;
q=read();
memset(head,,sizeof(head));
for(int i=;i<=q;i++)
{
ans1=;ans2=inf;ans3=;
k=read();cnt=k;num=;
for(int j=;j<=k;j++)now[j]=read(),vis[now[j]]=;
sort(now+,now+k+,cmp);
build();dfs();
for(int j=;j<=cnt;j++)vis[now[j]]=;
for(int j=;j<=num;j++)head[dian[j]]=;num=;
printf("%lld %d %d\n",ans1,ans2,ans3);
}
return ;
}
bzoj2286
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 500005
#define inf 0x3f3f3f3f
using namespace std;
int n;
int head[N],ver[N*],nxt[N*],quan[N*],tot;
inline int read()
{
int p=;char c=getchar();
while(c<''||c>'')c=getchar();
while(c>=''&&c<='')p=p*+c-'',c=getchar();
return p;
}
void add(int a,int b,int c)
{
tot++;nxt[tot]=head[a];head[a]=tot;ver[tot]=b;quan[tot]=c;
}
int fa[N][],mn[N][],dep[N];
void lca()
{
for(int i=;i<=;i++)
{
for(int j=;j<=n;j++)
{
fa[j][i]=fa[fa[j][i-]][i-];
mn[j][i]=min(mn[j][i-],mn[fa[j][i-]][i-]);
}
}
return ;
}
int lca(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);
for(int i=;i>=;i--)if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
if(x==y)return x;
for(int i=;i>=;i--)
{
if(fa[x][i]!=fa[y][i])
{
x=fa[x][i];y=fa[y][i];
}
}
return fa[x][];
}
int z,dfn[N];
void dfs(int x,int f)
{
dfn[x]=++z;
for(int i=head[x];i;i=nxt[i])
{
if(ver[i]==f)continue;
dep[ver[i]]=dep[x]+;
fa[ver[i]][]=x;
mn[ver[i]][]=quan[i];
dfs(ver[i],x);
}return ;
}
int now[N],cnt;
int vis[N],st[N],top;
int dian[N],num;
int qur(int x,int y)
{
int ans=inf;
for(int i=;i>=;i--)
{
if(dep[fa[x][i]]>=dep[y])
{
ans=min(ans,mn[x][i]);
x=fa[x][i];
}
}
return ans;
}
void build()
{
tot=;
st[]=;top=;
for(int i=;i<=cnt;i++)
{
if(now[i]==)continue;
int v=now[i];
int la=lca(st[top],v);
if(la!=st[top])
{
while(top>=&&dep[st[top-]]>dep[la])
{
add(st[top-],st[top],qur(st[top],st[top-])),top--;
}
add(la,st[top],qur(st[top],la));top--;
if(la!=st[top])st[++top]=la;
}
st[++top]=v;
}
while(top>=)
{
add(st[top-],st[top],qur(st[top],st[top-])),top--;
}
return ;
}
long long f[N];
bool cmp(int x,int y)//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
{
return dfn[x]<dfn[y];
}
void dp(int x)
{
dian[++num]=x;f[x]=;
for(int i=head[x];i;i=nxt[i])
{
dp(ver[i]);
if(vis[ver[i]])f[x]+=quan[i];
else f[x]+=min((long long)quan[i],f[ver[i]]);
}
return ;
}
int main()
{
n=read();
int t1,t2,t3,t4;
for(int i=;i<n;i++)
{
t1=read();t2=read();t3=read();
add(t1,t2,t3);add(t2,t1,t3);
}
mn[][]=inf;dep[]=;
dfs(,-);
lca();
memset(head,,sizeof(head));
int q,k;
q=read();
for(int i=;i<=q;i++)
{
k=read();cnt=k;num=;
for(int j=;j<=k;j++)
{
now[j]=read();vis[now[j]]=;
}
sort(now+,now+k+,cmp);build();
dp();
printf("%lld\n",f[]);
for(int j=;j<=k;j++)vis[now[j]]=;
for(int j=;j<=num;j++)head[dian[j]]=;
}
return ;
}
bzoj 3611: [Heoi2014]大工程 && bzoj 2286: [Sdoi2011消耗战的更多相关文章
- bzoj 3611 [Heoi2014]大工程(虚树+DP)
3611: [Heoi2014]大工程 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 408 Solved: 190[Submit][Status] ...
- bzoj 3611: [Heoi2014]大工程 虚树
题目: 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上. 在 2 个国家 a,b 之间建一条新通道需要的代价为树上 ...
- bzoj 3611[Heoi2014]大工程 虚树+dp
题意: 给一棵树 每次选 k 个关键点,然后在它们两两之间 新建 C(k,2)条 新通道. 求: 1.这些新通道的代价和 2.这些新通道中代价最小的是多少 3.这些新通道中代价最大的是多少 分析:较常 ...
- bzoj 3611: [Heoi2014]大工程
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #d ...
- BZOJ.3611.[HEOI2014]大工程(虚树 树形DP)
题目链接 要求的和.最大值.最小值好像都可以通过O(n)的树形DP做,总询问点数<=2n. 于是建虚树就可以了.具体DP见DP()函数,维护三个值sum[],mx[],mn[]. sum[]要开 ...
- BZOJ 3611 [Heoi2014]大工程 ——虚树
虚树第二题.... 同BZOJ2286 #include <map> #include <cmath> #include <queue> #include < ...
- 3611: [Heoi2014]大工程
3611: [Heoi2014]大工程 链接 分析: 树形dp+虚树. 首先建立虚树,在虚树上dp. dp:sum[i]为i的子树中所有询问点之间的和.siz[i]为i的子树中有多少询问点,mn[i] ...
- BZOJ2286 [Sdoi2011]消耗战 和 BZOJ3611 [Heoi2014]大工程
2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6371 Solved: 2496[Submit][Statu ...
- [Bzoj3611][Heoi2014]大工程(虚树)
3611: [Heoi2014]大工程 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 2000 Solved: 837[Submit][Status ...
随机推荐
- (一)Hyperledger Fabric 1.1安装部署-基础环境搭建
在学习和开发hyperledger fabric的时候遇到了一些坑,现将自己的一些总结和心得整理如下,以期对大家有所帮助.本次使用的宿主机环境:ubuntu,版本:Ubuntu 16.04.3 LTS ...
- python FTP服务器实现(Python3)
创建一个ftp.py文件(Linux环境),插入以下代码: from pyftpdlib.authorizers import DummyAuthorizer from pyftpdlib.handl ...
- Python参数传递,既不是传值也不是传引用
面试的时候,有没有被问到Python传参是传引用还是传值这种问题?有没有听到过Python传参既不是传值也不是传引用这种说法?一个小小的参数默认值也可能让代码出现难以查找的bug? 如果你也遇到过上面 ...
- Redux和React-Redux的实现(三):中间件的原理和applyMiddleware、Thunk的实现
现在我们的Redux和React-Redux已经基本实现了,在Redux中,触发一个action,reducer立即就能算出相应的state,如果我要过一会才让reducer计算state呢怎么办?也 ...
- 始入OO课程的殿堂,初识面向对象的奥妙——OO第一次博客总结
当我满怀期待叩开OO的大门,却发现宝藏藏在层层阻难之后 第一次作业 1.度量分析 >关于第一次作业的metrics图分析没有出现标红的McCabe Cyclomatic Complexity或者 ...
- 四则运算结对项目之GUI
本次结对编程让我学到了许多许多知识,受益匪浅!在此之前,我没想过我能做出一个双击运行的小程序. 感谢我的队友与我同心协力,感谢室友宇欣告诉我操作符为“最多多少”而不是“多少”并教我使用效能分析工具,感 ...
- angularJS1笔记-(14)-自定义指令(scope)
index.html: <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...
- Unity3d学习日记(六)
今天在研究怎么在unity中将image上的图片保存到本地,主要参考下面两个链接:Unity Texture2D缩放.UNITY存储图片到本地 结合上述两个链接,我写了如下代码来将缩放后或者改 ...
- PHP学习心得1
php是动态网站开发的优秀语言,在学习的时候万万不能冒进.在系统的学习前,我认为不应该只是追求实现某种效果,因为即使你复制他人的代码调试成功,实现了你所期望的效果,你也不了解其中的原理,这样你很难利用 ...
- Go 自学笔记
1. 最近花时间简单自学了一下go语言的语法..为了保证自己不是每次从0 开始 这次简单进行一下记录 保证 学习 效果. 2. 安装 直接下载go的包 进行安装 以及 暗转goland2018.3 进 ...